Вызовы Python и WinDLL не возвращаются из вызова DLL - PullRequest
0 голосов
/ 18 ноября 2018

Моя DLL имеет следующую функцию:

extern "C" __declspec(dllexport) bool __cdecl  PcapOpen(unsigned long inSize, void * inData, unsigned long *outSize, void * outData, Function_Modes eMode)

Функция будет записывать данные через outSize и outData (что означает, что они должны быть переданы в функцию в расчете на то, что моя функция внутри DLL изменит их)

Кроме того, Function_Modes равно:

typedef enum Function_Modes { Mode_Unknown = -1, Mode_Preview = 0, Mode_Execute = 1, Mode_Query } Function_Modes;

Для справки в Perl я ссылался на функцию так:

my %Data;
$Data{Interface} = $interface;
my ($inData, $inSize) = buildData(\%Data);
$$outSize = pack("L", 65536);

$outData = "\x00"x65536;

my $pPcapOpen = Win32::API->new($dllName, "PcapOpen", "NPPPI", "I", "_cdecl");
my $return = $pPcapOpen->Call($inSize, $inData, $$outSize, $outData, $eMode);

Я создал небольшой код Python, который должен запускать функцию и отображать данные, которые она возвращает, но вызов, пока «появляется доступ к DLL», не возвращается (код Python сразу после вызова никогда не вызывается)

pPcapDLL = ctypes.WinDLL("Pcap Interface.dll")

LP_c_char = ctypes.POINTER(ctypes.create_string_buffer(65536).__class__)                                                                                                  
obuf = ctypes.create_string_buffer(65536)
obuflen = ctypes.c_ulong(65536)
optr = LP_c_char(obuf)

PcapOpen = pPcapDLL["PcapOpen"]
PcapOpen.restype = ctypes.c_bool
PcapOpen.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.POINTER(LP_c_char), ctypes.POINTER(ctypes.c_size_t), ctypes.c_int]

outSize = ctypes.c_ulong(65536)

LP_c_char = ctypes.POINTER(ctypes.create_string_buffer(65536).__class__)                                                                                                  
outData = ctypes.create_string_buffer(65536)
outData_ptr = LP_c_char(outData)

print("Calling PcapClose")
returnValue = PcapClose(inSize, inData, ctypes.byref(outSize), ctypes.byref(outData_ptr), eMode)

print("returnValue: {}".format(returnValue)) # <-- This doesn't get called

Похоже, очень мало документации о том, как обрабатывать функции DLL, которые возвращают данные, - только то, что следует использовать byref, но не совсем ясно, как распределить данные для этих функций, чтобы использовать их - так что это может быть моим выпуск

Спасибо за помощь.

1 Ответ

0 голосов
/ 20 ноября 2018

На мой взгляд, необходимо внести два изменения:

  1. Функция C, которую вы пытаетесь вызвать, использует соглашение о вызовах cdecl, поэтому вы должны получить доступ к DLLиспользуя ctypes.cdll, а не ctypes.windll.ctypes.windll используется для stdcall соглашения о вызовах.См. Также документацию Python ctypes .

  2. Четвертый аргумент вашей функции - указатель, но вы, похоже, передаете ему указатель на указатель.Попробуйте заменить ctypes.byref(outdata_ptr) на ctypes.byref(outdata).

...