在C中嵌入Python,链接失败,未定义引用`Py_Initialize'

Mig*_*imo 8 c python python-c-extension

我正在尝试从文档https://docs.python.org/2.7/extending/embedding.html编译示例,我的代码看起来与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");

  Py_Finalize();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用以下命令编译它,它对我来说很好,并给我所需的目标文件:

gcc -c $(python2.7-config --cflags) embedpy.c
Run Code Online (Sandbox Code Playgroud)

要链接它,我使用以下命令,最终出现以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我无法找出我做错了什么,或者我忘了让这个例子工作.

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 
Run Code Online (Sandbox Code Playgroud)

nos*_*nos 16

链接时,库必须在目标文件之后,所以:

gcc  embedpy.o $(/usr/bin/python2.7-config --ldflags)
Run Code Online (Sandbox Code Playgroud)

  • 这对python3.5不起作用 (2认同)

Cir*_*四事件 8

还添加--embedpython3-config

在 Ubuntu 20.04、Python 3.8 上,我还需要传递--embed给 python3-config,如下所示:

gcc -std=c99 -ggdb3 -O0 -pedantic-errors -Wall -Wextra \
  -fpie $(python3-config --cflags --embed) -o 'eval.out' \
  'eval.c' $(python3-config --embed --ldflags)
Run Code Online (Sandbox Code Playgroud)

否则-lpython3.8不添加导致定义丢失。

这是我的测试程序:

评估文件

#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;
}
Run Code Online (Sandbox Code Playgroud)

测试运行:

./eval.out 'print(2 ** 3)'
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢!--embed 非常重要!!!!!! (2认同)