简体   繁体   中英

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

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM