2013-04-10 22 views
9

Sto provando a creare il mio primo esempio Boost.Python.Ho bisogno di aiuto per iniziare con Boost.Python

#include <iostream> 
#include <boost/python.hpp> 

using namespace boost::python; 


class Hello { 

public: 
    std::string greet() { 
     std::cout << "Hello World" << std::endl; 
    } 
}; 


BOOST_PYTHON_MODULE(hello) 
{ 
    class_<Hello>("Hello") 
     .def("greet", &Hello::greet); 
} 

int main() { 
    std::cout << "Boost.Python Test" << std::endl; 
    Hello hello; 
    hello.greet(); 
    return 0; 
} 

MODIFICA: mancavano le intestazioni di sviluppo Python, come ha sottolineato @cdhowie. Ho trovato e incluso i file di intestazione richiesti. Ora il linker si lamenta:

10:43:58 **** Build of configuration BoostPythonTest-DPar for project BoostPythonTest 

**** 
make all 
Building file: ../src/BoostPythonTest.cpp 
Invoking: GCC C++ Compiler 
/usr/local/bin/g++-4.7 -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -I/usr/include -I/usr/local/Cellar/gcc/4.7.2/gcc/include/c++/4.7.2 -O0 -g3 -p -pg -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"src/BoostPythonTest.d" -MT"src/BoostPythonTest.d" -o "src/BoostPythonTest.o" "../src/BoostPythonTest.cpp" 
Finished building: ../src/BoostPythonTest.cpp 

Building target: libBoostPythonTest-DPar.dylib 
Invoking: MacOS X C++ Linker 
/usr/local/bin/g++-4.7 -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config-3.3m -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/lib -L/usr/local/Cellar/boost/1.51.0/lib -std=c++11 -Xlinker -ldl -framework CoreFoundation -lpython3.3m -dynamiclib -o "libBoostPythonTest-DPar.dylib" ./src/BoostPythonTest.o -lpython3.3m -lboost_python-mt -lpython3.3 
Undefined symbols for architecture x86_64: 
    "boost::python::detail::init_module(PyModuleDef&, void (*)())", referenced from: 
     _PyInit_hello in BoostPythonTest.o 
ld: symbol(s) not found for architecture x86_64 
collect2: error: ld returned 1 exit status 
make: *** [libBoostPythonTest-DPar.dylib] Error 1 

ho già collegato a -lpython3.3m -lboost_python-mt -lpython3.3 - che altro manca?

EDIT: Penso di aver collegato tutto ciò che elenca python3.3-config. Il collegamento continua a non funzionare a causa di simboli mancanti.

risposta

12

Quando si verifica questo particolare errore del linker, è spesso il risultato della creazione dell'applicazione rispetto a una versione di Python, ad esempio i file di intestazione Python 3.x, mentre la libreria boost_python è stata creata su una versione diversa, ad esempio 2. X.

In boost/python/module_init.hpp, la funzione init_module ha il seguente identificativo quando si costruisce contro Python 3.x:

PyObject* boost::python::detail::init_module(PyModuleDef&, void(*)()); 

e la seguente firma quando si costruisce contro Python 2.x:

PyObject* boost::python::detail::init_module(char const* name, void(*)()); 

Come può essere visto nel implementation, solo una delle funzioni sarà presente nella libreria Boost.Python. Quindi, dato che la libreria Boost.Python è collegata, e il linker si lamenta solo di non essere in grado di risolvere la funzione 3.x init_module, è molto probabile che la libreria Boost.Python sia stata costruita su Python 2. versione x, mentre il codice dell'applicazione è stato creato con i file header di Python 3.x. È possibile verificare ciò scaricando i simboli della libreria Boost.Python e controllando la firma init_module.

Per risolvere questo problema, creare l'applicazione con la stessa versione di Python da cui è stato creato Boost.Python. In questo caso:

  • Creare l'applicazione con i file di intestazione 2.x di Python e il collegamento con le librerie Python 2.x.
  • Costruisci Boost.Python contro Python 3.x.La documentazione di This descrive la procedura per creare Boost e la documentazione di this entra nei dettagli di Boost.Python. Potrebbe essere necessario fornire esplicitamente l'eseguibile Python da cui verrà creato Boost.Python durante il processo bootstrap utilizzando l'argomento --with-python.
+0

Credo che tu abbia diagnosticato correttamente il problema. Ora sto provando a costruire Boost.Python contro Python 3.3. – clstaudt

+0

Quando provo a creare Boost.Python ottengo [il seguente errore] (https://gist.github.com/anonymous/5433641). 'gcc.link.dll ../../../../bin.v2/libs/python/build/gcc-4.2.1/debug/libboost_python.dylib ld: warning: directory non trovata per l'opzione ' -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config ' ld: opzione sconosciuta: -R collect2: ld restituito 1 stato di uscita' Cosa sta succedendo qui? – clstaudt

+1

@cls: Se si utilizza la versione di Apple della toolchain GCC, provare a specificare il set di strumenti come 'darwin' anziché' gcc'. –

6

Ti mancano le intestazioni di sviluppo Python. La tua distribuzione Linux dovrebbe avere un pacchetto per loro. (Ad esempio, python-dev su Debian o Ubuntu.)

+1

Grazie per aver segnalato l'errore. Ma io sono su OSX, qualche idea su come ottenere le intestazioni? L'homebrew non sembra avere una formula 'python-dev'. – clstaudt

+1

@cls Non utilizzo OS X, quindi non posso fornire alcun consiglio. Forse qualcun altro può. – cdhowie

+0

Trovate le intestazioni, ma ci sono problemi con il linker e mi piacerebbe che l'esempio funzionasse. – clstaudt

2

Si sta creando una libreria condivisa, perché è quello che è un modulo Python binario. Per questo, è necessario -shared o -dynamic (controllare i documenti) e non si dovrebbe avere una funzione main().

Inoltre, se ciò non aiuta e si hanno ancora errori del linker, utilizzare "objdump -T --demangle/path/to/lib" per scoprire quali simboli contiene una libreria e se ha quelli che si bisogno. Controlla anche l'output di "ldd", che elenca gli oggetti condivisi dipendenti. Questo dovrebbe darti un suggerimento su quale libreria o librerie collegare.

Sul mio sistema, ho anche un programma chiamato "python-config" e "python2.7-config". Controlla se hai qualcosa di simile, perché questo script sa quali librerie collegare almeno per python. Uno strumento simile è pkg-config, che è più generale e potrebbe fornire anche informazioni per l'aumento.

+0

'python3.3-config' mi dà alcuni percorsi e flag che ho aggiunto, ma senza alcun effetto (vedi chiamate sopra). 'otool' (che apparentemente è l'equivalente OSX di' objdump') mi dà ad es. '$ otool -T libboost_python-mt.dylib libboost_python-mt.dylib: Sommario (0 voci) indice del simbolo indice modulo'. 'ldd' non sembra esistere su OSX. – clstaudt

2

Non sono sicuro se questo è il modo per farlo, ma sembra che PY_VERSION_HEX sia impostato in modo errato. Cosa succede se si

#define PY_VERSION_HEX 0x03300000 

prima di includere le intestazioni Boost.Python nel BoostPythonTest.cpp?

+0

Questo è un commento, non una risposta. –

Problemi correlati