У меня есть Windows DLL, которая предоставляет функцию. Давайте назовем это Fn
. Он принимает два CStrings
в качестве параметров и возвращает CString
:
CString Fn(CString a, CString b)
Код C ++, который вы видите ниже, успешно загружает DLL и вызывает Fn
. Побочный эффект Fn
заключается в том, что он выводит значение параметра a
в stdtout. Итак, я вижу:
Parameter a has value "A"
Однако, когда я делаю то же самое из Python, я получаю:
Parameter a has value "B"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: exception: access violation reading 0x00000005
Так что Fn
каким-то образом получает параметр b
вместо параметра a
.
Мой вопрос: почему параметры моей функции искажаются при вызове DLL из Python, а не из C ++?
На самом деле, эта проблема непроисходят только когда я вызываю Fn
из Python, но также когда я звоню из NSIS через:
System::Call "My::Fn(m 'A', m 'B') m .r0"
Я думал, что это может быть проблемой с соглашением о вызовах. Поэтому я изменил windll.LoadLibrary
на cdll.LoadLibrary
. К сожалению, это дает точно такой же вывод.
Код Python (не работает)
from ctypes import *
f = windll.LoadLibrary('My.dll').Fn
f.argtypes = [c_char_p, c_char_p]
f.restype = c_char_p
f(b"A", b"B")
Код C ++ (работает)
#include <atlstr.h>
typedef CString (*Fn)(CString, CString);
int main( void ) {
HINSTANCE dll = LoadLibrary("My.dll");
Fn f = (Fn) GetProcAddress(dll, "Fn");
f("A", "B");
FreeLibrary(dll);
return 0;
}