Вызов Python и WinDLL не возвращается из вызова DLL

Моя 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, но не на 100% понятно, как выделить данные для этих функций, чтобы их использовать - так что это может быть моей проблемой

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

Пара (возможно, наивных) комментариев: 1. Функция объявлена ​​как __cdecl, но вы упоминаете WinDLL в заголовке вопроса. Не могли бы вы отредактировать свой код, чтобы указать, как вы загружаете свою DLL (т.е. откуда берется pPcapDLL)? 2. Вы пробовали заменить ctypes.byref(outdata_ptr) на ctypes.byref(outdata)? В его нынешнем виде похоже, что ваш код передает указатель на указатель на вашу функцию, тогда как кажется, что он принимает только указатель.

Luke Woodward 18.11.2018 15:27

Я исправил вопрос, я попробую outdata_ptr => outdata -> только что попробовал, я получаю «ValueError: процедура, вероятно, вызвана со слишком большим количеством аргументов (20 байтов больше)»

Noam Rathaus 19.11.2018 10:03
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
138
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

Я постараюсь сообщить тебе

Noam Rathaus 26.11.2018 08:15

Другие вопросы по теме