我想用ctypes
将一些C代码SIGMAFP_SDK包装成Python,
但是下面的语法让我很困惑
操作系统:Windows10Pro Python版本:3.8.5
这是我的C头文件
typedef struct _SDK_INFO
{
void *lpInterface;
HANDLE hMultipleOpenSync;
void *lpDataIn;
void *lpDataOut;
void *lpDataInBig;
void *lpDataOutBig;
DWORD dwDataInSize;
DWORD dwDataOutSize;
DWORD dwLastSendSize;
DWORD dwLastRecvSize;
BOOL bLastUseBugBuffer;
BOOL bUseBuffer;
DWORD dwDataInSizeBig;
DWORD dwDataOutSizeBig;
} SDK_INFO, *LPSDK_INFO;
typedef struct tag_RATIONAL {
ULONG ulNumerator;
ULONG ulDenominator;
} RATIONAL;
typedef struct tag_SRATIONAL {
LONG lNumerator;
LONG lDenominator;
} SRATIONAL;
typedef struct tag_ImageFileDirectory {
WORD wTagId;
WORD wType;
DWORD dwCount;
union
{
DWORD_PTR ulData;
VOID* lpData;
CHAR* lpAscii;
BYTE* lpByte;
USHORT* lpShort;
ULONG* lpLong;
RATIONAL* lpRational;
CHAR* lpSbyte;
BYTE* lpUndefined;
SHORT* lpSshort;
LONG* lpSlong;
SRATIONAL* lpSrational;
FLOAT* lpFloat;
DOUBLE* lpDouble;
} Value;
} ImageFileDirectory;
typedef struct tag_IFDArray {
DWORD dwDirectoryCount;
ImageFileDirectory* imageFileDirectory;
} IFDArray;
typedef IFDArray APIConfigTag;
HRESULT WINAPI sgm_ConfigAPI(LPSDK_INFO lpInfo, APIConfigTag *apiConfigTag);
我将上面的代码包装成python代码,如下所示
class _LPSDK_INFO(ctypes.Structure):
_fields_ = [('lpInterface', ctypes.c_char_p),
('hMultipleOpenSync', wintypes.HANDLE),
('lpDataIn', ctypes.c_char_p),
('lpDataOut', ctypes.c_char_p),
('lpDataInBig', ctypes.c_char_p),
('lpDataOutBig', ctypes.c_char_p),
('dwDataInSize', wintypes.DWORD),
('dwDataOutSize', wintypes.DWORD),
('dwLastSendSize', wintypes.DWORD),
('dwLastRecvSize', wintypes.DWORD),
('bLastUseBugBuffer', wintypes.BOOL),
('bUseBuffer', ctypes.c_bool),
('dwDataInSizeBig', wintypes.DWORD),
('dwDataOutSizeBig', wintypes.DWORD)]
class _RATIONAL(ctypes.Structure):
_fields_ = [('ulNumerator', wintypes.ULONG),
('ulDenominator', wintypes.ULONG)]
class _SRATIONAL(ctypes.Structure):
_fields_ = [('lNumerator', wintypes.LONG),
('lDenominator', wintypes.LONG)]
class _Value(ctypes.Union):
_fields_ = [('ulData', ctypes.c_longlong),
('lpData', wintypes.LPVOID),
('lpAscii', wintypes.PCHAR),
('lpByte', wintypes.PBYTE),
('lpShort', wintypes.PUSHORT),
('lpLong', wintypes.PULONG),
('lpRational', ctypes.POINTER(_RATIONAL)),
('lpSbyte', wintypes.PCHAR),
('lpUndefined', wintypes.PBYTE),
('lpSshort', wintypes.PSHORT),
('lpSlong', wintypes.PLONG),
('lpSrational', ctypes.POINTER(_SRATIONAL)),
('lpFloat', wintypes.PFLOAT),
('lpDouble', ctypes.POINTER(ctypes.c_double))]
class _ImageFileDirectory(ctypes.Structure):
_fields_ = [('wTagId', wintypes.WORD),
('wType', wintypes.WORD),
('dwCount', wintypes.DWORD),
('Value', ctypes.POINTER(_Value))]
class _APIConfigTag(ctypes.Structure):
_fields_ = [('dwDirectoryCount', wintypes.DWORD),
('imageFileDirectory', ctypes.POINTER(_ImageFileDirectory))]
if __name__ == '__main__':
lpInfo = _LPSDK_INFO()
apiConfigTag = _APIConfigTag()
source_dir = os.path.dirname(__file__)
SGM_CONFIGAPI = ctypes.CDLL(source_dir + '/dll/SIGMA_ConfigAPI.dll')
c_sgm_ConfigAPI = SGM_CONFIGAPI.sgm_ConfigAPI
c_sgm_ConfigAPI.restype = ctypes.c_long
c_sgm_ConfigAPI.argtypes = [ctypes.POINTER(_LPSDK_INFO), ctypes.POINTER(_APIConfigTag)]
result = c_sgm_ConfigAPI(ctypes.byref(lpInfo), ctypes.byref(apiConfigTag))
print(f'c_sgm_ConfigAPI.result = {hex(result)}')
print(f'apiConfigTag.dwDirectoryCount: {apiConfigTag.dwDirectoryCount}')
print(f'apiConfigTag.imageFileDirectory.wTagId: {apiConfigTag.imageFileDirectory.wTagId}') # How can i reference wTagId's value?
print(f'apiConfigTag.imageFileDirectory.wTagId.Value.ulData: {apiConfigTag.imageFileDirectory.wTagId.Value.ulData}') # And how about this value of wTagId.Value.ulData?
如果我删除代码上面的最后两行并执行它。 它工作正常
但我添加了最后两行并执行它 面对以下错误:
AttributeError: 'LP__ImageFileDirectory' object has no attribute 'wTagId'
如何取消对值的引用
要取消对指针的引用,需要使用
contents
。然后可以访问它所指向的结构或联合的成员。例如:相关问题 更多 >
编程相关推荐