2012-03-22 9 views
6

Voglio iniziare a imparare di più sull'utilizzo di SWIG e altri metodi per interfacciare Python e C++. Per iniziare, ho voluto compilare questo semplice programma di cui al another post:Tentativo di comprendere la procedura di collegamento per scrivere l'ibrido Python/C++

#include <Python.h> 

int main() 
{ 
     Py_Initialize(); 
     PyRun_SimpleString ("import sys; sys.path.insert(0, '/home/ely/Desktop/Python/C-Python/')"); 

     PyObject* pModule = NULL; 
     PyObject* pFunc = NULL; 

     pModule = PyImport_ImportModule("hello"); 
     if(pModule == NULL){ 
      printf("Error importing module."); 
      exit(-1); 
     } 


     pFunc = PyObject_GetAttrString(pModule, "Hello"); 
     PyEval_CallObject(pFunc, NULL); 
     Py_Finalize(); 
     return 0; 
} 

in cui il file "hello.py" ha appena il contenuto:

def Hello(): 
    print "Hello world!" 

Nota: ho già python2 .7-dev e python-dev e libboost-python-dev installati. Ma quando vado a compilare il codice, ottengo errori che credo siano dovuti al collegamento errato alle librerie Python.

[email protected]:~/Desktop/Python/C-Python$ gcc -I/usr/include/python2.7 test.cpp /tmp/ccVnzwDp.o: In function `main': 
test.cpp:(.text+0x9): undefined reference to `Py_Initialize' 
test.cpp:(.text+0x23): undefined reference to `PyImport_ImportModule' 
test.cpp:(.text+0x58): undefined reference to `PyObject_GetAttrString' 
test.cpp:(.text+0x72): undefined reference to `PyEval_CallObjectWithKeywords' 
test.cpp:(.text+0x77): undefined reference to `Py_Finalize' 
/tmp/ccVnzwDp.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0' 
collect2: ld returned 1 exit status 

Stavo pescando in giro per gli esempi di questo in linea, e ho trovato la seguente sintassi, che fa sì che il codice per compilare in un file oggetto, ma poi non sono in grado di eseguire effettivamente il file.

[email protected]:~/Desktop/Python/C-Python$ gcc -c -g -I/usr/include/python2.7 test.cpp 
[email protected]:~/Desktop/Python/C-Python$ ./test.o 
bash: ./test.o: Permission denied 
[email protected]:~/Desktop/Python/C-Python$ chmod ug=rx ./test.o 
[email protected]:~/Desktop/Python/C-Python$ ./test.o 
bash: ./test.o: cannot execute binary file 
[email protected]:~/Desktop/Python/C-Python$ sudo chmod ug=rx ./test.o 
[email protected]:~/Desktop/Python/C-Python$ ./test.o 
bash: ./test.o: cannot execute binary file 

Lo stesso comportamento come sopra si vede ancora se uso g++ anziché gcc.

Aiutare a capire il mio errore nel collegamento sarebbe grande, e ancora meglio per qualsiasi tipo di spiegazione che mi aiuti a capire la "logica" dietro il tipo di collegamento che devo fare, in modo che ricorderò meglio ciò che è possibile cose che sto dimenticando la prossima volta. Grazie!

+1

Un'altra osservazione: non è possibile eseguire direttamente i file '.o'. Per prima cosa è necessario collegarli a un eseguibile 'ELF'. – ulidtko

risposta

8

Quello che stai vedendo sono errori di linker. Per risolvere questi, è necessario collegare la libreria python2.7.

provare la prossima linea:

gcc -I/usr/include/python2.7 test.c -lpython2.7 

dovrebbe funzionare.

+1

Che cos'è 'kel.cpp'? Dovrebbe essere sostituito con il mio file di esempio 'test.cpp'? In tal caso, ricevo ancora un errore: 'ely @ AMDESK: ~/Desktop/Python/C-Python $ gcc -I/usr/include/python2.7 test.cpp -lpython2.7' restituisce l'errore : '/tmp/ccaahL1m.o:(.eh_frame+0x12): riferimento non definito a' __gxx_personality_v0 ' collect2: ld ha restituito 1 stato di uscita ' – ely

+0

@EMS Ho chiamato il file kel.cpp. Risolto nella modifica. È strano che tu abbia ricevuto un errore. Quale distro stai usando? –

+1

@EMS, compila con 'g ++' non 'gcc'. –

1

In primo luogo, si compila codice C o C++?

Utilizzare il gcc per il primo e g++ per il secondo. Il codice C++ necessita di alcuni collegamenti aggiuntivi da eseguire.

Secondo: è necessario collegare il programma a libpython2.7.so per incorporare l'interprete in esso. Per fare ciò, aggiungi -lpython2.7 alla riga di comando gcc.

1

test.o non è il file eseguibile, è per questo che non è possibile eseguirlo.

Il nome predefinito per il programma è a.out, provare a farlo. È possibile specificare un nome per il proprio programma utilizzando l'opzione -o.

+1

... e rimuovi l'opzione della riga di comando '-c'. – ulidtko

Problemi correlati