关于从加载的DLL调用函数的基本Python问题

关于从加载的DLL调用函数的基本Python问题,python,dll,ctypes,Python,Dll,Ctypes,我在搜索和尝试了几个小时的各种示例后提出了这个问题,但我似乎无法从加载的DLL调用函数。我想如果有人能给我举个例子,我就能理解我做错了什么,并取得一些进步 首先,使用Python 3.3.3,我可以加载DLL,如下所示: import ctypes ftdi=ctypes.cdll.LoadLibrary('C:\\Python33\\DLLs\\FTCJTAG.dll') 我可以调用一个不需要任何参数的函数,然后得到一个有意义的数字。但是在多次尝试之后,我不知道如何将参数传递给函数(即指针、

我在搜索和尝试了几个小时的各种示例后提出了这个问题,但我似乎无法从加载的DLL调用函数。我想如果有人能给我举个例子,我就能理解我做错了什么,并取得一些进步

首先,使用Python 3.3.3,我可以加载DLL,如下所示:

import ctypes
ftdi=ctypes.cdll.LoadLibrary('C:\\Python33\\DLLs\\FTCJTAG.dll')
我可以调用一个不需要任何参数的函数,然后得到一个有意义的数字。但是在多次尝试之后,我不知道如何将参数传递给函数(即指针、字符串、数字)

例如,从
FTCJTAG.h
,我们有:

FTCJTAG_API
FTC_STATUS WINAPI JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize);
从DLL程序员指南:

FTC_STATUS JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize)

This function returns the version of this DLL.
Parameters

lpDllVersionBuffer Pointer to the buffer that receives the version of this DLL. 
The string will be NULL terminated.

dwBufferSize Length of the buffer created for the device name string. Set buffer 
length to a minimum of 10 characters.

Return Value

Returns FTC_SUCCESS if successful, otherwise the return value will be one of the
following error codes:

FTC_NULL_DLL_VERSION_BUFFER_POINTER
FTC_DLL_VERSION_BUFFER_TOO_SMALL*
因此,我尝试以下方法:

version_string = ctypes.c_char * 10
string_ptr=version_string()
ftdi.JTAG_GetDllVersion(string_ptr,ctypes.c_long(10))
我得到的是:

Traceback (most recent call last):
File "C:\Python33\Scripts\FTDI.py", line 5, in <module>
ftdi.JTAG_GetDllVersion(string_ptr,ctypes.c_long(10))
ValueError: Procedure called with not enough arguments (8 bytes missing) or wrong
calling convention
要调用此函数,我将执行以下操作:

x = ctypes.c_ulong
x_ptr = x()
ftdi.JTAG_GetNumDevices(x_ptr)
错误是:

Traceback (most recent call last):
File "C:\Python33\Scripts\FTDI.py", line 9, in <module>
ftdi.JTAG_GetNumDevices(x_ptr)
OSError: exception: access violation writing 0x00000000
回溯(最近一次呼叫最后一次):
文件“C:\Python33\Scripts\FTDI.py”,第9行,在
ftdi.JTAG_GetNumDevices(x_ptr)
OSError:异常:访问冲突写入0x00000000
我收集到的信息是,我没有将指针的正确地址传递给函数,但经过多次搜索后,仍然没有找到答案。我相信这是一件简单的事情……:)


再次感谢您抽出时间

表示,如果您试图使用错误的调用约定调用它,也会引发该异常。因此,您可能需要使用
windle
而不是
cdll

WINAPI
加载它,WINAPI是
\u stdcall
的宏(ctypes
windle
windle
)。请参阅中的“Windows数据类型”。此修饰符在64位窗口上被忽略,该窗口只有一个调用约定。请参阅上的x86调用约定列表。使用
ctypes.wintypes
中的类型定义可以简化您的生活。设置函数指针的
argtypes
使ctypes检查参数类型,例如
ftdi.JTAG\u GetNumDevices.argtypes=[wintypes.LPDWORD]
。然后通过引用传递参数:
x=wintypes.DWORD();result=ftdi.JTAG\u GetNumDevices(ctypes.byref(x))
@eryksun,感谢您提供的精彩信息!我现在能够调用这两个函数,没有错误。我能够打印出JTAG_GetDllVersion返回的字符串(“2.0”),JTAG_GetNumDevices返回一个0,我认为这是正确的,因为我认为我连接了一个高速设备。两个调用都返回状态0,表示成功。再次感谢您帮助新手!!:)@eryksun,我记得几年前的一些C/C++代码,还记得传递值和传递指针之间的区别。但作为Python的新手,它的工作方式似乎有所不同。我使用了<代码>(cType CyChar * 10)(),这是在DLL附带的示例C++代码中的方式。我尝试使用
version\u string=ctypes。创建\u string\u缓冲区(10)
,然后将
version\u string
传递给函数,它似乎也能工作。再次感谢您的帮助和信息<代码>创建字符串缓冲区(10)
返回
(c字符*10)(
)。它方便的地方是
buf=create\u string\u buffer(init)
。这相当于buf=(c_char*(len(init)+1));buf.value=init。请注意,
c_char*10
是一种数组类型。它比使用
\u type=c\u char
\u length=10
子类化
数组更方便。
Traceback (most recent call last):
File "C:\Python33\Scripts\FTDI.py", line 9, in <module>
ftdi.JTAG_GetNumDevices(x_ptr)
OSError: exception: access violation writing 0x00000000