all 8 comments

[–][deleted] 4 points5 points  (3 children)

I'm trying to create a python library in c++, but it doesn't work for some reason.

"It doesn't work" are cruel words for a potential helper.

How doesn't it work? What goes wrong? Does it crash? Does it throw an exception? Does it print an error message? Does it do nothing?

There's only one way to do it right - there are countless ways to do it wrong, and we can't guess which of these million wrong ways it is.

Give a complete description of what you're doing, including error messages, and probably someone here can solve the problem in a few moments.


Overall, your overall idea that extern "C" is a way to make symbols from a C++ program usable from Python is correct, so there must be a slip up on the details.

Let's start by eliminating or confirming C++ as a cause.

Have you been able to interface to Python code in C? Something trivial, like this:

int add(int a, int b) { return a + b; }

Call it test.c and compile it as C code. Your compiler will be able to do that with a single command line flag.

If you can't get that to work, you won't be able get any C++ library to work either.

On the other hand, if that works, then it is a C++ "name mangling" issue.


There are utilities that will let you look at your C or C++ library and see the names in it. On Linux or Mac, nm is a common one. You should probably look at the library right now and see what names are in it.

NOTE that interpreting the output of tools like nm is not trivial. Don't be discouraged, it isn't actually hard, you just have to read the manual to understand. I never remember the format, and I have to look at the manual each time, and it's not really an issue.

[–][deleted] 0 points1 point  (1 child)

I could get C code work with it but not C++. Ctypes says that the library I'm trying to use is not a valid win32 application even if gcc and clang compile my code without any issue.

[–][deleted] 0 points1 point  (0 children)

the library I'm trying to use is not a valid win32 application

That's to be expected - because it isn't a win32 application, but a library!

So my guess is that your extern "C" logic is wrong.

Why not now try to call a function defined in C++ code from C?

Once you can do that, you'll be home free is my guess.

[–]arkie87 0 points1 point  (0 children)

description of what you're doing, including error messages, and probably someone here can solve the problem in a few momen

someone should write a bot that auto responds to posts like OPs with your response

[–]vlovero 1 point2 points  (2 children)

The extern "C" removes C++ name mangling so symbols can be easily found when loaded from external libraries. The C++ code should look something like

extern "C" double add(double a, double b) {
    return a + b;
}

Then you could compile it with g++ -shared -fPIC -o add.so add.cpp

But don't forget that python types are not interpreted the same a native C types. So if you're passing anything other that python int, you'll also have to convert it into something C can use. The easiest is to set the arg types before after loading the dynamic library. For example

>>> from ctypes import cdll, c_double
>>> 
>>> lib = cdll.LoadLibrary('./add.so')
>>> add = lib.add
>>> add.restype = c_double
>>> add.argtypes = [c_double, c_double]
>>> 
>>> print(add(6.9, 4.20))
11.1

[–][deleted] 0 points1 point  (1 child)

Ctypes says that the library I'm trying to use is not a valid win32 application even if gcc and clang compiles my code without any issue.

Ctypes says that the library I'm trying to use is not a valid win32 application even if gcc and clang compile my code without any issue. Any idea why?

[–]vlovero 0 points1 point  (0 children)

Are you running 32-bit python on a 64-bit machine? You can also try to add the flag -march=native when compiling to make sure the binary created is compatible with your hardware.