Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ctypes error AttributeError symbol not found, OS X 10.7.5

Tags:

c++

python

ctypes

I have a simple test function on C++:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>

char fun() {
    printf( "%i", 12 );

   return 'y';
}

compiling:

gcc -o test.so -shared -fPIC test.cpp

and using it in python with ctypes:

from ctypes import cdll
from ctypes import c_char_p

lib = cdll.LoadLibrary('test.so')
hello = lib.fun
hello.restype = c_char_p

print('res', hello())

but then I get an error:

Traceback (most recent call last):   File "./sort_c.py", line 10, in <module>
    hello = lib.fun   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 366, in __getattr__
    func = self.__getitem__(name)   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 371, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self)) 
AttributeError: dlsym(0x100979b40, fun): symbol not found

Where is a problem?

using:

Mac Os X 10.7.5 and Python 2.7

like image 391
pasichnyk.oleh Avatar asked Jun 22 '15 14:06

pasichnyk.oleh


1 Answers

Your first problem is C++ name mangling. If you run nm on your .so file you will get something like this:

nm test.so
0000000000000f40 T __Z3funv
                 U _printf
                 U dyld_stub_binder

If you mark it as C style when compiled with C++:

#ifdef __cplusplus
extern "C" char fun()
#else
char fun(void)
#endif
{
    printf( "%i", 12 );

   return 'y';
}

nm gives:

0000000000000f40 T _fun
                 U _printf
                 U dyld_stub_binder

Your second problem is that the python will die with a Segmentation fault: 11 (on OS X). The C++ is returning a char, whereas you are marking it in python as a pointer to a char. Use:

hello.restype = c_char

instead (alter your import statement to match).

EDIT: as @eryksun pointed out, you should not use gcc, you should use g++ instead. Otherwise the correct C++ runtime will not be linked. To check on OS X:

otool -L test.so

(ldd, the tool normally used on UNIX/Linux, is not distributed with OS X)

like image 107
cdarke Avatar answered Oct 18 '22 07:10

cdarke