我使用过MFC的C ++ dll,我想从python中调用它。 此dll在.h文件中包含此标头
LONG CommOpen(BYTE port, LONG baud_rate);
然后我在自由软件dllexp中看到我的函数被调用了?CommOpen @ CFIPcmd @@ QAEJEJ @ Z在二进制文件中所以当我在python中没有报告错误
import ctypes
lib = ctypes.WinDLL('C:\\Users\\toto\\FIProtocol.dll')
prototype = WINFUNCTYPE(c_long, c_byte, c_long)
testPt = ctypes.WINFUNCTYPE (prototype)
testApi = testPt (("?CommOpen@CFIPcmd@@QAEJEJ@Z", lib))
直到它似乎工作,但我想在Python中调用相当于
的C ++Long l= CommOpen(5 ,115200);
但我没有发现如何继续。 任何帮助都会非常感激!!
答案 0 :(得分:4)
鉴于问题中提供的信息,解决方案是:
import ctypes
lib = ctypes.CDLL(r'C:\Users\toto\FIProtocol.dll')
CommOpen = getattr(lib, "?CommOpen@CFIPcmd@@QAEJEJ@Z")
CommOpen.argtypes = [c_byte, c_long]
CommOpen.restype = c_long
现在可以打电话了:
l = CommOpen(5 ,115200)
一些注意事项:
CDLL
而不是WinDLL
,因为该函数使用默认的cdecl
调用约定。getattr
可以指定损坏的名称。argtypes
和restype
总是值得的。然而,事实证明你有一个更大的问题。以上是基于您的函数是非成员函数。考虑到ctypes
要求函数是非成员函数或静态函数,这是一个合理的假设。
但是,当我将托管函数名称放入一个解映射器(例如http://pear.warosu.org/c++filtjs/)时,似乎该函数实际上是这样的:
public: long __thiscall CFIPcmd::CommOpen(unsigned char,long)
这是C ++对象的成员函数。无法从ctypes
访问。您需要创建一个普通的C风格包装器,或者找到一种不同的互操作方法。
答案 1 :(得分:0)
根据http://docs.python.org/2/library/ctypes.html#calling-functions“你可以调用这些函数,就像任何其他Python可调用一样。”我建议运行一个交互式Python控制台(如ipython)并自行检查。
好吧,我刚刚将Python安装到VirtualBox Win32并检查了示例:
>>> from ctypes import * >>> f = getattr(cdll.msvcrt, "??2@YAPAXI@Z") >>> f <_FuncPtr object at 0x00B7EDC8> >>> f() 24969248 >>> _
所以,是的,您可以像python环境中的任何其他函数一样调用这些函数对象。正如文件所声称的那样:)
同样_cputws有效:
>>> cputws = getattr(cdll.msvcrt, "_cputws") >>> r = cputws("Hello, World!\n") Hello, World! >>> r 0 >>>