在C中嵌入Python时,链接失败,引用未定义为'Py#u Initialize';
我试图从文档中编译示例,我的代码与5.1中的代码完全相同:在C中嵌入Python时,链接失败,引用未定义为'Py#u Initialize';,python,c,python-c-extension,Python,C,Python C Extension,我试图从文档中编译示例,我的代码与5.1中的代码完全相同: #include <Python.h> int main(int argc, char *argv[]) { Py_SetProgramName(argv[0]); Py_Initialize(); PyRun_SimpleString("from time import time, ctime\n" "print 'Today is', ctime(time())\n
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("from time import time, ctime\n"
"print 'Today is', ctime(time())\n");
Py_Finalize();
return 0;
}
要链接它,我使用以下命令,该命令最终导致以下错误:
gcc $(/usr/bin/python2.7-config --ldflags) embedpy.o
embedpy.o: In function `main':
/home/miguellissimo/embedpy.c:6: undefined reference to `Py_SetProgramName'
/home/miguellissimo/embedpy.c:7: undefined reference to `Py_Initialize'
/home/miguellissimo/embedpy.c:8: undefined reference to `PyRun_SimpleStringFlags'
/home/miguellissimo/embedpy.c:11: undefined reference to `Py_Finalize'
collect2: error: ld returned 1 exit status
我不知道我做错了什么,也不知道我忘记了什么来让这个例子起作用
PS:python2.7-config命令在我的Xubuntu机器上提供以下输出:
>>> python2.7-config --cflags
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -fno-stri
ct-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=
4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-pr
ototypes
>>> python2.7-config --ldflags
-L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpthread -ldl -luti
l -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
链接时,库必须位于对象文件之后,因此:
gcc embedpy.o $(/usr/bin/python2.7-config --ldflags)
我在Win7机器上运行的Lubuntu14.04 32位虚拟机上复制了相同的问题 在C++ Eclipse C/C++开发环境中编写C++代码的第一个地方,我做了以下的事情来复制这个问题。定义了一个名为“test”的C++ Eclipse项目。源文件包含以下C++代码,与上面提到的MiguelsiSimo相同。 C++代码::
#include "python2.7/Python.h"
int main(int argc, char *argv[]) {
Py_Initialize();
PyRun_SimpleString("print \"Hello, world!\"");
Py_Finalize();
return 0;
}
错误::
测试o:在函数main'中:
/home/ros/workspace/test/src/test.cpp:15:未定义的引用
/home/ros/workspace/test/src/test.cpp:17:PyRun\u SimpleStringFlags的未定义引用
/home/ros/workspace/test/src/test.cpp:18:未定义对
Py_Finalize'的引用
collect2:错误:ld返回了1个退出状态
以下命令的输出与Miguellissimo之前提到的相同
ros@rosPC:~/workspace/test/src$ python2.7-config --cflags
-I/usr/include/python2.7 -I/usr/include/i386-linux-gnu/python2.7 -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
ros@rosPC:~/workspace/test/src$ python2.7-config --ldflags
-L/usr/lib/python2.7/config-i386-linux-gnu -L/usr/lib -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
< C++ Eclipse项目名为“test”的项目属性::
内部,我有以下C++构建设置
GCC C++编译器< /P>
Command: g++
All options: -I/opt/ros/indigo/include -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
Command: g++
All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/include/python2.7
GCC编译器
Command: gcc
All options: -I/opt/ros/indigo/include -I/usr/lib/python2.7/config-i386-linux-gnu -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/lib/python2.7/config-i386-linux-gnu
Command: gcc
All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/include/python2.7
<> GCC C++链接器< /P>
Command: g++
All options: Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Libraries:
Libraries(-I):
Library search path(-L):
Command: g++
All options: -L/usr/lib/python2.7/config-i386-linux-gnu
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Libraries:
Libraries(-I): python2.7
Library search path(-L): /usr/lib/python2.7/config-i386-linux-gnu
解决方案:
在C++ Eclipse项目“测试”
项目属性中指定以下C++生成设置GCC C++编译器< /P>
Command: g++
All options: -I/opt/ros/indigo/include -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
Command: g++
All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/include/python2.7
GCC编译器
Command: gcc
All options: -I/opt/ros/indigo/include -I/usr/lib/python2.7/config-i386-linux-gnu -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/lib/python2.7/config-i386-linux-gnu
Command: gcc
All options: -I/opt/ros/indigo/include -I/usr/include/python2.7 -O0 -g3 -Wall -c -fmessage-length=0
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Includes
include paths: /opt/ros/indigo/include
/usr/include/python2.7
<> GCC C++链接器< /P>
Command: g++
All options: Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Libraries:
Libraries(-I):
Library search path(-L):
Command: g++
All options: -L/usr/lib/python2.7/config-i386-linux-gnu
Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Libraries:
Libraries(-I): python2.7
Library search path(-L): /usr/lib/python2.7/config-i386-linux-gnu
<>结果:链接C++编译程序中以前出现的链接错误不再发生。 < P> <强>也添加<代码>嵌入 > <代码> Python 3配置> <代码> <强> < /P>
在Ubuntu20.04和python3.8上,我还需要将--embed
传递给python3配置,如下所示:
gcc -std=c99 -ggdb3 -O0 -pedantic-errors -Wall -Wextra \
-fpie $(python3-config --cflags --embed) -o 'eval.out' \
'eval.c' $(python3-config --embed --ldflags)
否则,不会添加-lpython3.8
,这会导致缺少定义
这是我的测试程序:
评估c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main(int argc, char *argv[]) {
(void)argc;
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program);
Py_Initialize();
PyRun_SimpleString(argv[1]);
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
在WSL、Ubuntu18.04、Python3.8、g++7.5上也出现了同样的错误。 多亏了Ciro Santilli的评论,将
--embed
选项添加到python3.8-config
解决了未解决的符号问题,但在此之后,我得到了以下错误:
gcc $(/usr/bin/python2.7-config --ldflags) embedpy.o
embedpy.o: In function `main':
/home/miguellissimo/embedpy.c:6: undefined reference to `Py_SetProgramName'
/home/miguellissimo/embedpy.c:7: undefined reference to `Py_Initialize'
/home/miguellissimo/embedpy.c:8: undefined reference to `PyRun_SimpleStringFlags'
/home/miguellissimo/embedpy.c:11: undefined reference to `Py_Finalize'
collect2: error: ld returned 1 exit status
g++`python3.8-config--cflags--embed`-o cpython.out cpython.cpp`python3.8-config--ldflags--embed`
lto1:致命错误:文件“/home/rpovelik/installed/miniconda3/envs/cython/lib/python3.8/config-3.8-x86_64-linux-gnu/libpython3.8.a”中的字节码流是用LTO版本6.0而不是预期的6.2生成的
编译终止。
lto包装器:致命错误:g++返回1个退出状态
编译终止。
/usr/bin/ld:错误:lto包装失败
collect2:错误:ld返回了1个退出状态
我想有些人会面临同样的问题,所以我检查了conda的类似症状,他们说“不要使用默认编译器-g++
,因为这可能会导致兼容性问题-使用conda特定的编译器”
顺便说一下,添加
-fno lto
解决了我在系统范围g++7.5
的问题。可能您可以尝试更改编译器的版本。接受的答案使用系统的默认库位置
如果您在蟒蛇环境中,可能找不到库位置。我倾向于在链接过程中更明确地给出位置,例如:
gcc embedpy.o -L$(python-config --prefix)/lib $(python-config --ldflags)
这在64位库中的anaconda环境之外不起作用,在这种情况下:
gcc embedpy.o -L$(python-config --prefix)/lib64 $(python-config --ldflags)
尝试在编译行中包含
-I/usr/include/python2.7-lpython2.7
。第一个已经在那里了,在编译行中添加-lpython2.7似乎没有什么作用。它可以像以前一样编译为对象文件,但链接不正确-lpython2.7也已经添加到用于linkingI的第二个gcc命令中,我能够将C链接到python程序。虽然这会加载一个模块而不是整个程序,但这可能会有所帮助。CC=gcc CCFLAGS=-I/usr/include/python3.5/-I/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu/-c-w-lpython3.5 LLFLAGS=$(/usr/bin/python3.5-config--ldflags)所有:$(CC)$(CCFLAGS)TerrainPredict.c$(CC)TerrainPredict.o$(LLFLAGS)非常感谢!嵌入是非常重要的!!!!!!