从 Python 调用的 C++ dll
我在 MFC 中使用了一个 C++ dll,我想从 python 中调用它.此 dll 在 .h 文件中包含此标头
I have used a C++ dll using MFC and I would like to call it from python. This dll contains this header in the .h file
LONG CommOpen(BYTE port, LONG baud_rate);
然后我在免费软件 dllexp 中看到我的函数在二进制文件中被称为 ?CommOpen@CFIPcmd@@QAEJEJ@Z 所以我在 python 中执行时不会报告错误
Then I see in the free software dllexp that my function is called ?CommOpen@CFIPcmd@@QAEJEJ@Z in the binary file so no error is reported when I do in 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++ 中的等价物
Until there it seems to work but then I would like to call the in Python the equivalent in C++ of
Long l= CommOpen(5 ,115200);
但我不知道如何进行.任何帮助将不胜感激!
But I Didn't find know how to proceed. Any help would be really appreciated!!
推荐答案
鉴于问题中提供的信息,解决方案是:
Given the information presented in the question, the solution is:
import ctypes
lib = ctypes.CDLL(r'C:Users otoFIProtocol.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
总是值得的.
- Use
CDLL
rather thanWinDLL
because the function used the defaultcdecl
calling convention. - Use
getattr
to be able to specify the mangled name. - It always pays to specify
argtypes
andrestype
explicitly.
<小时>
然而,你发现你有一个更大的问题.以上是在您的函数是非成员函数的基础上编写的.这是一个合理的假设,因为 ctypes
要求函数要么是非成员的,要么是静态的.
However, it transpires that you have a much greater problem. The above was written on the basis that your function is a non-member function. Which is a reasonable assumption given that ctypes
requires functions to be either non-member, or static.
但是,当我将您的托管函数名称放入 demanger 时(例如 http://pear.warosu.org/c++filtjs/) 看来函数其实是:
However, when I put your managed function name into a demanger (for instance http://pear.warosu.org/c++filtjs/) it seems that the function is in fact:
public: long __thiscall CFIPcmd::CommOpen(unsigned char,long)
这是一个 C++ 对象的成员函数.不能从 ctypes
访问.您需要创建一个普通的 C 样式包装器,或者找到一种不同的互操作方法.
That is a member function of a C++ object. That cannot be accessed from ctypes
. You'll need to create a plain C style wrapper, or find a different method of interop.
相关文章