pxg*_*pxg 3 c python ubuntu gcc
我有以下C程序,需要与Python集成:
#include <Python.h>
PyObject* get_details(){
PyObject *details = PyDict_New();
PyObject *key, *value;
key = PyUnicode_FromString("full name");
value = PyUnicode_FromString("Pete Graham");
PyDict_SetItem(details, key, value);
return details;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令在OS X上编译程序:
gcc -I /Library/Frameworks/Python.framework/Versions/3.4/Headers \
-L /Library/Frameworks/Python.framework/Versions/3.4/lib \
-lpython3.4 get_person_dict.c
Run Code Online (Sandbox Code Playgroud)
尝试在Ubuntu上编译程序时出现错误 /usr/bin/ld: cannot find -lpython3.4.
这是我在Ubuntu上使用的命令,我已经尝试了python lib路径的各种值。
gcc -I /usr/include/python3.4 \
-L /usr/local/lib \
-lpython3.4 get_person_dict.c
Run Code Online (Sandbox Code Playgroud)
我安装sudo apt-get install python3.4-dev了版本为Ubuntu trusty64的python,并在Vagrant上使用。
有几处错误。
正如@JJHakala所建议的那样,
python3.4-config --libs
Run Code Online (Sandbox Code Playgroud)
会告诉您所需的库,以便将可执行文件与Python 3.4运行时链接,即:
-lpython3.4m -lpthread -ldl -lutil -lm
Run Code Online (Sandbox Code Playgroud)
和
python3.4-config --ldflags
Run Code Online (Sandbox Code Playgroud)
将告诉您必须传递给链接器以实现相同目的的所有选项,即:
-L/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu \
-L/usr/lib -lpython3.4m -lpthread -ldl -lutil -lm \
-Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
Run Code Online (Sandbox Code Playgroud)
因此,让我们尝试将这些链接器选项放到您的gcc命令行中,而不是您曾经使用过的链接器选项中。您的命令行是:
$ gcc -I /usr/include/python3.4 -L/usr/local/lib -lpython3.4 get_person_dict.c
Run Code Online (Sandbox Code Playgroud)
带有链接器选项:
-L/usr/local/lib -lpython3.4
Run Code Online (Sandbox Code Playgroud)
因此,我们将尝试:
$ gcc -I /usr/include/python3.4 `python3.4-config --ldflags` get_person_dict.c
Run Code Online (Sandbox Code Playgroud)
那不行 输出为:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
/tmp/ccrczTMI.o: In function `get_details':
get_person_dict.c:(.text+0x9): undefined reference to `PyDict_New'
get_person_dict.c:(.text+0x17): undefined reference to `PyUnicode_FromString'
get_person_dict.c:(.text+0x25): undefined reference to `PyUnicode_FromString'
get_person_dict.c:(.text+0x40): undefined reference to `PyDict_SetItem'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我们有对在中调用的所有Python 3.4函数
get_person_dict.c的未定义引用,以及对的未定义引用main
使用未定义的Python 3.4引用的原因是,您曾经(现在)仍然将库传递给链接器,而不是调用它们中定义的函数的任何文件。因此,链接器依次进入命令行中的每个库并对自己说:
我是否已注意到对在此库中具有定义的未定义函数的任何调用?否。那么我不需要链接此库中的任何内容。并继续下去。在所有库都被忽略之后,它到达您的get_person_dict.c(或实际上/tmp/ccrczTMI.o是编译器以前从其编译的临时目标文件get_person_dict.c)。有未定义的引用认定PyDict_New,PyUnicode_FromString PyUnicode_FromString,
PyDict_SetItem。但是,现在没有可以在其中定义它们的库了。他们所在的图书馆被定义为桥下的水,所以未定义的引用仍为链接错误。
在链接顺序中,需要定义 的文件必须出现在提供定义的文件之前。
好吧,这很容易纠正:
$ gcc -I /usr/include/python3.4 get_person_dict.c `python3.4-config --ldflags`
Run Code Online (Sandbox Code Playgroud)
现在的输出是:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
现在,链接器已找到所有Python 3.4函数的定义。但它仍然说找不到的定义main。
原因是您发布的C“程序”不是程序,而只是函数的定义PyObject* get_details()。根据定义,每个C程序都有一个main函数,这是第一个调用的函数。因此,当您尝试将某些文件和库链接到C程序时,链接器会自动链接调用的启动代码
main。但是你没有main。
因此get_person_dict.c,即使您获得正确的链接顺序,也无法将您作为程序链接。您可以编译它,而无需链接它:
$ gcc -I /usr/include/python3.4 -c -o get_person_dict.o get_person_dict.c
Run Code Online (Sandbox Code Playgroud)
这将为您提供一个目标文件get_person_dict.o,其中包含的已编译但未链接的定义PyObject* get_details()。这将与/tmp/ccrczTMI.ogcc为您编译的临时目标文件相同,而不会在上述失败的编译和链接尝试中告知您。
但是,编译完这样的代码之后get_person_dict.o,您可以将其链接到程序中,只要您在此之后还链接其他定义该函数调用的库:
get_person_prog.c
#include <Python.h>
#include <stdio.h>
extern PyObject * get_details(); // Ought to be put in a header
int main(void)
{
PyObject * pyobj = get_details();
if (pyobj) {
puts("Got the details");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译:
$ gcc -I /usr/include/python3.4 -c -o get_person_prog.o get_person_prog.c
Run Code Online (Sandbox Code Playgroud)
以正确的顺序链接目标文件和库,以制作一个程序prog:
$ gcc -o prog get_person_prog.o get_person_dict.o `python3.4-config --ldflags`
Run Code Online (Sandbox Code Playgroud)
跑:
$ ./prog
Got the details
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2282 次 |
| 最近记录: |