2012-03-22 21 views
6

Tôi muốn bắt đầu tìm hiểu thêm về cách sử dụng SWIG và các phương thức khác để giao tiếp Python và C++. Để bắt đầu, tôi muốn để biên dịch chương trình đơn giản này đề cập đến trong another post:Cố gắng hiểu quy trình liên kết để viết Python/C++ hybrid

#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; 
} 

mà tập tin "hello.py" chỉ có các nội dung:

def Hello(): 
    print "Hello world!" 

Lưu ý: Tôi đã có python2 .7-dev và python-dev và libboost-python-dev được cài đặt. Nhưng khi tôi biên dịch mã, tôi nhận được các lỗi mà tôi tin là do liên kết không đúng với các thư viện 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 

Tôi đang tìm kiếm các ví dụ về trực tuyến này và tôi đã tìm cú pháp sau, khiến mã biên dịch thành tệp đối tượng, nhưng sau đó tôi không thể thực thi tệp.

[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 

Các hành vi tương tự như trên vẫn thấy nếu tôi sử dụng g++ thay vì gcc.

Giúp hiểu được lỗi của tôi khi liên kết sẽ tuyệt vời và thậm chí tốt hơn cho bất kỳ loại giải thích nào giúp tôi hiểu "logic" đằng sau loại liên kết tôi cần làm, để tôi nhớ rõ hơn những gì có thể những điều tôi quên trong lần sau. Cảm ơn!

+1

Một nhận xét khác: bạn không thể thực thi trực tiếp các tệp '.o'. Trước tiên, bạn cần phải liên kết chúng thành một tập tin thực thi 'ELF'. – ulidtko

Trả lời

8

Điều bạn đang thấy là lỗi trình liên kết. Để khắc phục chúng, bạn cần liên kết thư viện python2.7.

Hãy thử dòng tiếp theo:

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

cần làm việc.

+1

'kel.cpp' là gì? Điều đó có nên được thay thế bằng tập tin ví dụ 'test.cpp' của tôi không? Nếu vậy, tôi vẫn gặp lỗi: 'ely @ AMDESK: ~/Máy tính để bàn/Python/C-Python $ gcc -I/usr/include/python2.7 test.cpp -lpython2.7' cung cấp lỗi : '/tmp/ccaahL1m.o:(.eh_frame+0x12): tham chiếu không xác định đến' __gxx_personality_v0 ' collect2: ld trả lại 1 trạng thái thoát' – ely

+0

@EMS Tôi đã đặt tên tệp là kel.cpp. Đã sửa trong bản chỉnh sửa. Thật lạ khi bạn gặp lỗi. Bạn đang sử dụng distro nào? –

+1

@EMS, biên dịch với 'g ++' không phải' gcc'. –

1

Trước tiên, bạn có biên dịch mã C hoặc C++ không?

Sử dụng gcc cho mục cũ và g++ cho mục sau. Mã C++ cần thêm một số liên kết để thực hiện.

Thứ hai: bạn phải liên kết chương trình của mình với libpython2.7.so để nhúng trình thông dịch vào đó. Để thực hiện việc này, hãy thêm -lpython2.7 vào dòng lệnh gcc.

1

test.o không phải là tệp thi hành của bạn, đó là lý do tại sao bạn không thể thực thi nó.

Tên mặc định cho chương trình của bạn là a.out, hãy thử chạy điều đó. Bạn có thể chỉ định tên cho chương trình của mình bằng cách sử dụng tùy chọn -o.

+1

... và xóa tùy chọn dòng lệnh '-c'. – ulidtko

Các vấn đề liên quan