在 Python 中使用 Ctypes 读取 Dll 的双 c 结构
Reading double c structures of Dll with Ctypes in Python
我已经对这个问题进行了很多研究..但是没有地方,我找不到它。我试图通过调用 c dll 来调用双 c 结构。
我的问题是,我在 python 中声明 "Class Structure" 的方法是否正确?我不认为我是对的。因为即使我想从 dll 调用的函数,它也没有输出任何东西。
[Visual C++/C]
我确实尝试了 C 语法代码,
typedef sturct {
int nBoardNum;
struct{
char pBoardName[16];
int nBoardID;
}BOARDINDEX[8];
}AAPBOARDINFO, *PAAPBOARDINFO;
HANDLE AcapOpen(char* cpBoardName, int nBoardNo, int nCh)
[Python]
我把 Python 语法改成了这样。
import ctypes as c
class BOARDINDEX(c.Structure):
_field_ = [("nBoardName", c.c_char_p * 16),("nBoardID", c.c_int)]
class AAPBOARDINFO(c.Structure):
_field_ = [("nBoardNum", c.c_int), ("BOARDINDEX", BOARDINDEX * 8)]
AapLib2 = c.WinDLL("AapLib2.dll")
BoardName = ["ABC","FWD","HGW"]
BoardNo = 0
ch = 1
output = Open(BoardName, BoardNo, ch)
def Open(BoardName, BoardNo, ch)
func = AapLib2.AcapOpen
func.argtypes = [c.POINTER(BOARDINDEX),c.c_int, c.c_int]
func.restype = c.c_int
ref = BOARDINDEX()
res = func(c.byref(ref.nBoardName),BoardNo, ch)
return res
调用 Open() 函数时没有任何结果...
请考虑我的要求,任何答案都很好...
您需要知道的一切,都可以在 [Python 3.Docs]: ctypes - A foreign function library for Python.
中找到
代码有几个问题:
- 结构成员在 _fields_ 中指定(not _field_ ) 属性
char pBoardName[16]
映射到 ctypes.c_char * 16
(不是 c_char_p)
- HANDLE 应映射到
wintypes.HANDLE
。这种不匹配会(而且很可能会)产生:
- 函数原型在 C 和 Python
之间不同
- 最好避免使用像 AapLib2 这样的全局变量,但我将它们保持不变,因为它们超出了问题范围
这是您的代码的修改版本。不用说,我实际上并没有测试它,因为我没有 .dll:
#!/usr/bin/env python3
import sys
import ctypes
from ctypes import wintypes
class BOARDINDEX(ctypes.Structure):
_fields_ = [
("nBoardName", ctypes.c_char * 16),
("nBoardID", ctypes.c_int),
]
class AAPBOARDINFO(ctypes.Structure):
_fields_ = [
("nBoardNum", ctypes.c_int),
("BOARDINDEX", BOARDINDEX * 8),
]
def open_board(board_name, board_no, ch):
AcapOpen = aaplib2.AcapOpen
AcapOpen.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_int]
AcapOpen.restype = wintypes.HANDLE
ref = BOARDINDEX(board_name, board_no) # Probably this line should be replaced by the 3 (commented) ones below (AcapGetBoardInfo prototype would have to be specified as well)
#abi = AAPBOARDINFO()
#AcapGetBoardInfo(ctypes.byref(abi))
#ref = abi.BOARDINDEX[0]
res = AcapOpen(ref.nBoardName, ref.nBoardID, ch)
return res
def main():
board_names = ["ABC", "FWD", "HGW"]
board_no = 0
ch = 1
aaplib2 = ctypes.WinDLL("AapLib2.dll")
output = open_board(board_names[0], board_no, ch)
print(output)
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main()
print("\nDone.")
让我知道你的结果如何。
我已经对这个问题进行了很多研究..但是没有地方,我找不到它。我试图通过调用 c dll 来调用双 c 结构。
我的问题是,我在 python 中声明 "Class Structure" 的方法是否正确?我不认为我是对的。因为即使我想从 dll 调用的函数,它也没有输出任何东西。
[Visual C++/C]
我确实尝试了 C 语法代码,
typedef sturct {
int nBoardNum;
struct{
char pBoardName[16];
int nBoardID;
}BOARDINDEX[8];
}AAPBOARDINFO, *PAAPBOARDINFO;
HANDLE AcapOpen(char* cpBoardName, int nBoardNo, int nCh)
[Python]
我把 Python 语法改成了这样。
import ctypes as c
class BOARDINDEX(c.Structure):
_field_ = [("nBoardName", c.c_char_p * 16),("nBoardID", c.c_int)]
class AAPBOARDINFO(c.Structure):
_field_ = [("nBoardNum", c.c_int), ("BOARDINDEX", BOARDINDEX * 8)]
AapLib2 = c.WinDLL("AapLib2.dll")
BoardName = ["ABC","FWD","HGW"]
BoardNo = 0
ch = 1
output = Open(BoardName, BoardNo, ch)
def Open(BoardName, BoardNo, ch)
func = AapLib2.AcapOpen
func.argtypes = [c.POINTER(BOARDINDEX),c.c_int, c.c_int]
func.restype = c.c_int
ref = BOARDINDEX()
res = func(c.byref(ref.nBoardName),BoardNo, ch)
return res
调用 Open() 函数时没有任何结果...
请考虑我的要求,任何答案都很好...
您需要知道的一切,都可以在 [Python 3.Docs]: ctypes - A foreign function library for Python.
中找到代码有几个问题:
- 结构成员在 _fields_ 中指定(not _field_ ) 属性
char pBoardName[16]
映射到ctypes.c_char * 16
(不是 c_char_p)- HANDLE 应映射到
wintypes.HANDLE
。这种不匹配会(而且很可能会)产生: - 函数原型在 C 和 Python 之间不同
- 最好避免使用像 AapLib2 这样的全局变量,但我将它们保持不变,因为它们超出了问题范围
这是您的代码的修改版本。不用说,我实际上并没有测试它,因为我没有 .dll:
#!/usr/bin/env python3
import sys
import ctypes
from ctypes import wintypes
class BOARDINDEX(ctypes.Structure):
_fields_ = [
("nBoardName", ctypes.c_char * 16),
("nBoardID", ctypes.c_int),
]
class AAPBOARDINFO(ctypes.Structure):
_fields_ = [
("nBoardNum", ctypes.c_int),
("BOARDINDEX", BOARDINDEX * 8),
]
def open_board(board_name, board_no, ch):
AcapOpen = aaplib2.AcapOpen
AcapOpen.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_int]
AcapOpen.restype = wintypes.HANDLE
ref = BOARDINDEX(board_name, board_no) # Probably this line should be replaced by the 3 (commented) ones below (AcapGetBoardInfo prototype would have to be specified as well)
#abi = AAPBOARDINFO()
#AcapGetBoardInfo(ctypes.byref(abi))
#ref = abi.BOARDINDEX[0]
res = AcapOpen(ref.nBoardName, ref.nBoardID, ch)
return res
def main():
board_names = ["ABC", "FWD", "HGW"]
board_no = 0
ch = 1
aaplib2 = ctypes.WinDLL("AapLib2.dll")
output = open_board(board_names[0], board_no, ch)
print(output)
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main()
print("\nDone.")
让我知道你的结果如何。