Wrapping c++ functions in python with ctypes on windows : function not found

空扰寡人 提交于 2019-12-08 00:50:14

问题


I need to run a series of python scripts calculating various scripts, that are working fine, but one of them runs very slowly and has to be done in C++. The C++ code is ready, but I need to find a way to call the C++ function from the python and get the return value.

I found information about SWIG, but didn't get it to work on Windows with Visual Studio (I have to do it in VS on Windows, because of other constraints). I found ctypes much easier for my very simple function with standart input and output values.

So I did many tests with ctypes, tried all the examples I could find online, and each and every time, what happens is that I can load the dll (built with visual studio 2012 compiler) but when I try calling the function in python, it just goes :

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print maLib.plop()
  File "C:\Python27\lib\ctypes\__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python27\lib\ctypes\__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'plop' not found

The python code is (test.py) :

from ctypes import cdll
lib = cdll.LoadLibrary('test')
print lib.plop()

The C++ code is (test.cpp, compiled as test.dll, Visual Studio set to build as dll) :

extern "C"
{
    int plop();
}

int plop() { return 4; }

As you can see, I tried to make it as simple as possible, to avoid details making it fail. I have read the python ctypes help, and tutorials on how to use ctypes, trying exactly the same codes as them, but I had to adapt a bit because I am using Visual Studio / windows and most of the other users are using linux. All of the files are in the same folder.

I have tried multiple ways of loading the library : LoadLibrary('./name.dll'), WinDLL('name.dll'), giving the function a different name, void return type, etc...

Do you think I should use SWIG ? Is my problem an obvious beginner mistake ? I am a student, and new to most of what I'm using, but I put a lot of effort in this, even if I just need it for a particular single task. When using SWIG, I had to make a wrapper with function pointers, or references, so I thought this was the problem, which made me want to try a simpler solution.

I am using : Python 2.7.7, Visual Studio 2012, Windows 8.1

Many thanks in advance


回答1:


The error reported by your Python is very clear.

function 'plop' not found

This means that the DLL does not export a function of that name. So, you need to export the function. Either with a .def file, or using __declspec(dllexport):

extern "C"
{
    __declspec(dllexport) int plop();
}

To inspect your DLL to debug issues like this, use dumpbin or Dependency Walker.

Note that since you do not specify calling convention, the default of __cdecl is used. That means that cdll is correct on the ctypes side.




回答2:


You need to give your function "C" linkage to avoid name mangling. Declare it like this:

extern "C"
{
    int plop();
}

and it will then properly be called "plop" rather than being name-mangled.



来源:https://stackoverflow.com/questions/24575348/wrapping-c-functions-in-python-with-ctypes-on-windows-function-not-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!