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);
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))
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\toto\FIProtocol.dll')
CommOpen = getattr(lib, "?CommOpen@CFIPcmd@@QAEJEJ@Z")
CommOpen.argtypes = [c_byte, c_long]
CommOpen.restype = c_long
And now it is ready to call:
l = CommOpen(5 ,115200)
Some notes:
- Use
CDLL
rather than WinDLL
because the function used the default cdecl
calling convention.
- Use
getattr
to be able to specify the mangled name.
- It always pays to specify
argtypes
and restype
explicitly.
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.
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)
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.
According to http://docs.python.org/2/library/ctypes.html#calling-functions "You can call these functions like any other Python callable." I would suggest to run an interactive Python console (like ipython) and check it yourself.
Well, I've just installed python into VirtualBox Win32 and checked the example:
>>> from ctypes import *
>>> f = getattr(cdll.msvcrt, "??2@YAPAXI@Z")
>>> f
<_FuncPtr object at 0x00B7EDC8>
>>> f()
24969248
>>> _
So, yes, you may call those function objects like any other function in the python environment. Just as the documentation claims :)
Likewise _cputws works:
>>> cputws = getattr(cdll.msvcrt, "_cputws")
>>> r = cputws("Hello, World!\n")
Hello, World!
>>> r
0
>>>