如何解决Python 3使用自定义数据类型调用外部DLL
我正在尝试使用C中的以下标头定义调用外部DLL。
typedef long EPC_INT32;
typedef void* EPC_ADDR32;
typedef struct {EPC_CHAR a [16];} EPC_Str16;
typedef struct
{
EPC_INT32 UseUSB;
EPC_INT32 BoardNumber;
EPC_INT32 FIFOSamples;
EPC_INT32 MaxProbes;
EPC_Str16 DeviceNumber;
EPC_Str16 SerialNumber;
EPC_INT32 ExternalScaling;
EPC_ADDR32 DacScaling;
EPC_ADDR32 AdcScaling;
} LIH_OptionsType;
typedef LIH_OptionsType* LIH_OptionsPtr;
EPC_INT32 EPC_Calling LIH_InitializeInterface(
EPC_Str256Ptr ErrorMessage,EPC_INT32 Amplifier,EPC_INT32 ADBoard,LIH_OptionsPtr OptionsPtr,EPC_INT32 OptionsSize ) EPC_Import;
Python代码:
import ctypes
import sys
class LIH_Options(ctypes.Structure):
_fields_ = [("UseUSB",ctypes.c_int32),("BoardNumber",("FIFOSamples",("MaxProbes",("DeviceNumber",ctypes.c_wchar_p),("SerialNumber",("ExternalScaling",("DataScaling",ctypes.c_void_p),("AdcScaling",ctypes.c_void_p)]
OptionsSize = sys.getsizeof(LIH_Options)
my_LIH_Options = LIH_Options(0,1024,'',0) #create an instance
EPC = ctypes.WinDLL('EpcDLL.dll')
EPC.LIH_InitializeInterface.argtypes = [ctypes.c_char_p,ctypes.c_int32,ctypes.POINTER(LIH_Options),ctypes.c_int32]
szErrMssg = ctypes.create_string_buffer(256)
status = EPC.LIH_InitializeInterface(szErrMssg,3,my_LIH_Options,OptionsSize)
这将返回Tracback错误: 状态= EPC.LIH_InitializeInterface(szErrMssg,0,int(LIH.Board),my_LIH_Options,OptionsSize) OSError:异常:写入0xFFFFFFFF的访问冲突
如果呼叫被替换为
status = EPC.LIH_InitializeInterface(szErrMssg,None,OptionsSize)
它可以使用LIH_Options的默认值。因此问题在于传递数据类型LIH_Options。
解决方法
数组类型和结构大小不正确。这应该可以工作,但未经测试,因为我没有您的DLL。 None
通常用于NULL指针,但0也应该起作用。将字节字符串(b''
)用于char
数组。
import ctypes
# define the types for easier match to original C structure.
EPC_INT32 = ctypes.c_int32;
EPC_ADDR32 = ctypes.c_void_p; # Only 32-bit on a 32-bit OS.
EPC_CHAR = ctypes.c_char; # Assumption...not defined in question
EPC_Str16 = EPC_CHAR * 16; # Correct type of char[16] array
class LIH_Options(ctypes.Structure):
_fields_ = [("UseUSB",EPC_INT32),("BoardNumber",("FIFOSamples",("MaxProbes",("DeviceNumber",EPC_Str16),("SerialNumber",("ExternalScaling",("DataScaling",EPC_ADDR32),("AdcScaling",EPC_ADDR32)]
OptionsSize = ctypes.sizeof(LIH_Options) # sys.getsizeof returns size of Python object,not C
my_LIH_Options = LIH_Options(0,1024,b'',None,None) #create an instance
EPC = ctypes.WinDLL('EpcDLL.dll')
EPC.LIH_InitializeInterface.argtypes = [ctypes.c_char_p,EPC_INT32,ctypes.POINTER(LIH_Options),EPC_INT32]
szErrMssg = ctypes.create_string_buffer(256)
status = EPC.LIH_InitializeInterface(szErrMssg,3,my_LIH_Options,OptionsSize)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。