首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Python嵌入C中,链接将失败,而未定义的引用将指向`Py_Initialize‘

将Python嵌入C中,链接将失败,而未定义的引用将指向`Py_Initialize‘
EN

Stack Overflow用户
提问于 2014-12-27 23:57:17
回答 5查看 27K关注 0票数 18

我正在尝试从docs https://docs.python.org/2.7/extending/embedding.html编译这个示例,我的代码看起来与5.1下面的代码完全一样:

代码语言:javascript
复制
#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;
}

我使用以下命令编译它,它对我很好,并给出了所需的对象文件:

代码语言:javascript
复制
gcc -c $(python2.7-config --cflags) embedpy.c

要链接它,我使用以下命令,它将导致以下错误:

代码语言:javascript
复制
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机器上提供了以下输出:

代码语言:javascript
复制
>>> 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 
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-12-28 00:37:56

在链接时,库必须位于对象文件之后,因此:

代码语言:javascript
复制
gcc  embedpy.o $(/usr/bin/python2.7-config --ldflags)
票数 20
EN

Stack Overflow用户

发布于 2020-05-13 18:42:42

还将添加到 python3-config

在Ubuntu20.04和Python3.8上,我还需要将--embed传递给python3-config,如下所示:

代码语言:javascript
复制
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,这会导致缺少定义。

这是我的测试程序:

eval.c

代码语言:javascript
复制
#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;
}

测试运行:

代码语言:javascript
复制
./eval.out 'print(2 ** 3)'
票数 18
EN

Stack Overflow用户

发布于 2020-05-15 06:57:27

在WSL、Ubuntu18.04、Python3.8、g++ 7.5上也有相同的错误。感谢Ciro的评论,将--embed选项添加到python3.8-config解决了未解决的符号问题,但在此之后,我得到了以下错误:

代码语言:javascript
复制
g++ `python3.8-config --cflags --embed` -o cpython.out cpython.cpp `python3.8-config --ldflags --embed`
lto1: fatal error: bytecode stream in file ‘/home/rpovelik/installed/miniconda3/envs/cython/lib/python3.8/config-3.8-x86_64-linux-gnu/libpython3.8.a’ generated with LTO version 6.0 instead of the expected 6.2
compilation terminated.
lto-wrapper: fatal error: g++ returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

我想有些人会面临同样的问题,所以我检查了类似的症状,这里,conda的人说,“不要使用默认编译器-- g++ --因为它可能导致兼容性问题--使用conda特定的编译器”。

顺便说一句,添加-fno-lto解决了我在系统范围内的g++ 7.5问题。可能您可以尝试更改编译器的版本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27672572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档