2012-06-28 4 views
8

Meine CMake Einstellung einer gemeinsamen lib in Linux zu erstellen, ist so etwas wieCtypes keine Symbole in gemeinsam genutzten Bibliothek zu finden, erstellt mit CMake

SET (CMAKE_CXX_FLAGS "-fPIC") 

SET (LIB_UTILS_SRC 
    Utils.cpp 
) 

ADD_LIBRARY (UTILS SHARED 
    ${LIB_UTILS_SRC} 
) 

Quelle Utils.cpp

double addTwoNumber(double x, double y) 
{ 
    return x + y; 
} 

Wenn für den Zugriff ‚versucht addTwoNumber 'Funktion mit CTypes wie

import os 
import ctypes as c 

libPath = '/home/AP/workspace/LearningCPP/lib/libUTILS.so' 
libUTILS = c.cdll.LoadLibrary(libPath) 

prototype = c.CFUNCTYPE( 
    c.c_double,     
    c.c_double,     
    c.c_double     
) 
addTwoNumber = prototype(('addTwoNumber', libUTILS)) 

res = addTwoNumber(c.c_double(2.3), c.c_double(3.5)) 

Ich bekomme eine Nachricht wie.

AttributeError: /home/AP/workspace/LearningCPP/lib/libUTILS.so: 
undefined symbol: addTwoNumber 

überprüfte ich die libUTILS.so den "nm --demangle libUTILS.so" Befehl und es zeigt deutlich das Symbol 'addTwoNumber' drin.

Warum bekomme ich immer noch die Nachricht "undefined symbol" von Python? Ich vermute, dass einige Compiler-Flags gesetzt werden müssen, damit die Symbole richtig funktionieren. Jeder Vorschlag wäre willkommen!

Antwort

15

Interessant, verwende ich normalerweise numpy.ctypes, da ich ständig mit großen Datensätzen zu tun habe, und hatte nie irgendwelche Probleme, aber ich denke, ich weiß, was hier los ist, ist es, dass die Namen durch den g ++ Compiler, ich gemacht wurde gemangelt es funktioniert auf diese Weise:

Makefile:

g++ -Wall -fPIC -O2 -c Utils.cpp 
g++ -shared -Wl -o libUTILS.so Utils.o 

Utils.cpp

extern "C" double addTwoNumber(double x, double y) 
{ 
    return x + y; 
} 

test.py

import os 
import ctypes as c 

libUTILS = c.cdll.LoadLibrary('libUTILS.so') 

prototype = c.CFUNCTYPE( 
    c.c_double,     
    c.c_double,     
    c.c_double     
) 
addTwoNumber = prototype(('addTwoNumber', libUTILS)) 

res = addTwoNumber(c.c_double(2.3), c.c_double(3.5)) 
print res 

Ausgang:

$ python test.py 
5.8 

Notiz das extern Schlüsselwort dies stellt sicher, dass der Compiler den Namen nicht mangle, Sie haben einige zusätzliche Dinge zu tun, wenn sie unter Windows, habe ich http://wolfprojects.altervista.org/dllforpyinc.php finden, die Art war interessant.

Ich hoffe, das hilft.

meine Maschine:

$ g ++ --version
i686-apple-darwin10-g ++ - 4.2.1 (GCC) 4.2.1 (Apple Inc. bauen 5666) (Punkt 3) Urheberrecht (C) 2007 Freie Software-Grundlage, Inc. Dies ist freie Software; Siehe die Quelle für Kopierbedingungen. Es gibt keine Garantie; nicht einmal für MARKTGÄNGIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.

$ uname -a
Darwin MacBookPro 10.8.0 Darwin Kernel Version 10.8.0: Di Jun 7 16:33:36 PDT 2011; root: xnu-1504.15.3 ~ 1/RELEASE_I386 i386

+2

Danke dafür. Ich hatte das gleiche Problem - es stellte sich heraus, dass ich einfach alle C "Funktionen" externalisieren musste (wie auch in der Python-Dokumentation im Abschnitt [Python mit C oder C++ erweitern] erwähnt) (http: // docs. python.org/2/extending/extending.html#writing-extensions-in-c)). – Breakthrough

Verwandte Themen