2015-05-20 2 views
2

как в python 3.4.3, так и в 2.7.9 при попытке вызвать любую функцию из библиотеки ядра.Python 32bit на Windows 64bit Ошибка модуля Ctypes

от 32-битной версии питона на 64-битных Windows, появляется сообщение об ошибке напечатал:

from ctypes import * 
path=create_string_buffer(256) 
rs=cdll.Kernel32.GetModuleFileNameA(0,path,256) 
print (path) 

ошибка заключается в следующем:

Traceback (most recent call last): 
     File "test-ctypes.py", line 3, in <module> 
     ValueError: Procedure called with not enough arguments (12 bytes missing) or wrong calling convention 
+0

Возможный дубликат [Python ctypes и недостаточно аргументов (отсутствует 4 байта)] (http://stackoverflow.com/questions/1458813/python-ctypes-and-not-enough-arguments-4-bytes-missing) –

+0

, даже если я определил функцию argtypes и restype, проблема возникла. – Aladdin

ответ

4

Сообщение об исключении говорит вам ответ:

ValueError: процедура, вызванная с , недостаточно аргументов (12 байт отсутствует) или неправильное соглашение о вызове

Число аргументов является правильным, поэтому оно должно быть другим: вы используете неправильное соглашение о вызове. Вызывающее соглашение - это способ, которым компилятор сопоставляет три аргумента в C, чтобы сохранить фактические значения в памяти при вызове функции (среди нескольких других вещей). На MSDN documentation for GetModuleFileA вы найдете следующую подпись

DWORD WINAPI GetModuleFileName(
    _In_opt_ HMODULE hModule, 
    _Out_ LPTSTR lpFilename, 
    _In_  DWORD nSize 
); 

WINAPI говорит компилятору использовать stdcall соглашение о вызовах. В коде ctypes используется cdll, который, с другой стороны, принимает cdecl вызов convetion. Решение простое: изменение cdll к windll:

from ctypes import * 
path=create_string_buffer(256) 
rs=windll.Kernel32.GetModuleFileNameA(0,path,256) 
print (path) 

Сравните с ctypes documentation for accessing .dll's, где kernel32 будет явно показано, использовать windll.

+0

Я действительно искал, как явно использовать конкретный callcanvention – Aladdin

+0

@ user3406177, более идиоматично использовать 'None' при передаче значения указателя« NULL ». Кроме того, если вы не определяете его 'restype' и' argtypes', 'GetModuleFileNameA' не будет работать должным образом в 64-битной Windows. Используйте типы Windows, определенные в 'ctypes.wintypes'. Кроме того, используйте 'kernel32 = WinDLL ('kernel32')', если вы создаете библиотеку. – eryksun

Смежные вопросы