Форум сайта python.su
Создаю простейшую с помощью MinGW dll с двумя функциями:
#include <windows.h>
extern "C" __declspec(dllexport) void SomeFunction(double data)
{
if (data < 0)
MessageBoxA(0, "less than zero", "DLL Message", MB_OK | MB_ICONERROR);
}
extern "C" __declspec(dllexport) void EmptyFunction()
{
MessageBoxA(0, "EmptyFunction", "DLL Message", MB_OK | MB_ICONERROR);
}
from ctypes import *
from ctypes.wintypes import*
EmptyFunction = WINFUNCTYPE(None)(
("EmptyFunction", windll.first_dll))
SomeFunction = WINFUNCTYPE(None, c_double)(
("SomeFunction", windll.first_dll), ((1, "data", 0.0),))
EmptyFunction()
SomeFunction(-1.0)
Traceback (most recent call last):
File "....py", line 11, in <module>
SomeFunction(-1.0)
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
Офлайн
WINFUNCTYPE используется только для python callback.
Вам нужно писать что-то вроде
SomeFunction = windll.firts_dll
SomeFunction.argtypes =
Офлайн
Попробовал так:
SomeFunction = windll.first_dll.SomeFunction
SomeFunction.argtypes = [c_double]
Офлайн
Ээээ. calling conventions?
windll - это stdcall. По умолчанию в msvc используется cdecl, насколько я помню. Или меняйте windll на cdll или пишите в заголовке
extern “C” __declspec(dllexport) void __stdcall SomeFunction(double data);
Офлайн
Андрей СветловЕсли было бы так, то функции совсем бы не находились. Но они находятся, и даже данные передаются, но почему-то после передачи данных вызывается исключение.
Ээээ. calling conventions?
Офлайн
Вру. Прошел без исключений такой вариант (без __stdcall):
SomeFunction = cdll.first_dll.SomeFunction
SomeFunction.argtypes =
Однако, со __stdcall и windll почему то не сработало.
Ладно. Буду отсыпаться и читать теорию, может и пойму :)
Офлайн
Есть два ортогональных понятия: calling conventions и name mangling.
Первое отвечает за то, как параметры ложатся на стек и регистры, откуда берется возвращаемое значение и кто стек чистит. К слову, в amd64 (он же x86_64) есть только один calling convention и это здорово. Он вполне универсален и подходит на все случаи жизни.
Второе пришло с С++. Когда-то был только С и имена в нем просто имели префикс “_”. Потом появился С++ и стало нужно как-то записывать “функция-член f класса A”. Каждый компилятор решал проблему по своему (не было и до сих пор нет единого стандарта). При этом для перегрузки функций по сигнатуре кодируют еще и типы принимаемых параметров.
Исключение про “что-то на стеке порушилось” относится к первому случаю.
Вдогонку - http://en.wikipedia.org/wiki/Name_mangling
Отредактировано (Фев. 12, 2010 22:22:46)
Офлайн