2015-06-22 10 views
5

ich eine einfache Testfunktion auf C++ haben:ctypes Fehler Attribute Symbol nicht gefunden, OS X 10.7.5

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

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

    return 'y'; 
} 

Compilierung:

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

und es in Python mit ctypes mit:

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()) 

aber dann bekomme ich einen Fehler:

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 

Wo ist ein Problem?

mit:

Mac Os X 10.7.5 and Python 2.7

Antwort

8

Ihr erstes Problem ist, C++ Name Mangeln. Wenn Sie nm auf .so Datei ausgeführt werden Sie etwas wie diese:

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

Wenn Sie es als C-Stil kennzeichnen, wenn sie mit C++ kompiliert:

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

    return 'y'; 
} 

nm gibt:

0000000000000f40 T _fun 
       U _printf 
       U dyld_stub_binder 

Ihr zweites Problem ist, dass der Python mit einem Segmentation fault: 11 (unter OS X) sterben wird. Das C++ gibt char zurück, während Sie es in Python als Zeiger auf ein Zeichen markieren. Verwendung:

hello.restype = c_char 

statt (ändern Sie Ihre import Aussage entsprechen).

EDIT: wie @eryksun wies darauf hin, sollten Sie nicht gcc verwenden, sollten Sie stattdessen g++ verwenden. Andernfalls wird die korrekte C++ - Laufzeit nicht verknüpft. Um zu überprüfen, auf OS X:

otool -L test.so 

(ldd, das Werkzeug normalerweise verwendete auf UNIX/Linux wird nicht mit O X verteilt)

+1

Does mit 'gcc' verknüpfen, um ein C++ Programm auf den richtigen C++ Runtime in OS X? Ich würde erwarten, dass es 'g ++' benötigt. Ich weiß, dass es in diesem Fall keine Rolle spielt, da der Beispielcode nur C-Standardbibliotheksfunktionen verwendet. – eryksun

+0

@eryksun: 'gcc' kompiliert es als C++, wenn die Quelldatei das Suffix' .cpp' hat, aber Sie haben Recht, 'g ++' wird bevorzugt. Ich habe es in meiner Antwort nicht erwähnt, weil es einen Kommentar dazu gab (deins?). Es ist nachweisbar C++, weil der Name mangling anders ist als das bedingte 'externe 'C'' (siehe Text des Posts). – cdarke

+1

'gcc' kompiliert die Quelle als C++, aber unter Linux wird keine Verbindung mit libstdC++ .so.6 hergestellt, daher schlägt das Laden der Bibliothek fehl, wenn die C++ - Bibliothek benötigt wird. – eryksun

Verwandte Themen