将Python嵌入C:链接错误-对PyString_AsString的未定义引用 [英] Embedding Python in C: Error in linking - undefined reference to PyString_AsString

查看:273
本文介绍了将Python嵌入C:链接错误-对PyString_AsString的未定义引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将python程序嵌入C程序中.我的操作系统是Ubuntu 14.04

I am trying to embed a python program inside a C program. My OS is Ubuntu 14.04

我尝试将python 2.7和python 3.4解释器嵌入到同一C代码库中(作为单独的应用程序).嵌入python 2.7时,编译和链接有效,但不嵌入python 3.4.在链接器阶段失败.

I try to embed python 2.7 and python 3.4 interpreter in the same C code base (as separate applications). The compilation and linking works when embedding python 2.7 but not for the python 3.4. It fails during the linker stage.

这是我的C代码(只是一个示例,不是真正的代码)

Here is my C code (just an example not real code)

simple.c

#include <stdio.h>
#include <Python.h>

int main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc, *pValue;
    char module[] = "get_version";
    char func[] = "get_version";
    char module_path[] = ".";

    Py_Initialize();
    PyObject *sys_path = PySys_GetObject("path");
    PyList_Append(sys_path, PyUnicode_FromString(module_path));

    pName = PyUnicode_FromString(module);
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if(pModule != NULL)
    {
        pFunc = PyObject_GetAttrString(pModule, func);
        if (pFunc && PyCallable_Check(pFunc))
        {
            pValue = PyObject_CallObject(pFunc, NULL);
            if (pValue != NULL) {
                printf("Python version: %s\n", PyString_AsString(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return 1;
            }
        }
    }

    Py_Finalize();
    return 0;
}

get_version.py

import sys

def get_version():
    version = '.'.join(str(v) for v in sys.version_info[:3])
    print("version: ", version)
    return version

我使用gcc编译程序.首先将编译和链接标志设置为python 2.7,然后使用以下命令运行编译和链接:

I compile the program using gcc. First with compiling and linking flags set to python 2.7 I run the compilation and linking by using following command:

gcc `python-config --cflags` simple.c `python-config --ldflags`

标志扩展为:

python-config --cflags: -I/usr/include/python2.7 -I/usr/include/x86_64-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

python-config --ldflags: -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

它运行正常,没有任何问题.当我尝试使用python3.4标志进行编译时,它失败了:

It works fine without any issues. When I try to compile the same with python3.4 flags it fails:

gcc `python3-config --cflags` simple.c `python3-config --ldflags`

标志扩展为:

python-config --cflags: -I/usr/include/python3.4m -I/usr/include/python3.4m -Wno-unused-result -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

python-config --ldflags: -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

错误消息:

simple.c: In function ‘main’:
simple.c:27:17: warning: implicit declaration of function ‘PyString_AsString’ [-Wimplicit-function-declaration]
                 printf("Python version: %s\n", PyString_AsString(pValue));
                 ^
simple.c:27:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
/tmp/ccaoMdTo.o: In function `main':
/home/vagrant/c_python_api/simple.c:27: undefined reference to `PyString_AsString'
collect2: error: ld returned 1 exit status

我尝试通过更改链接器对象的指定顺序.但是没有运气.知道为什么会是这种情况吗?

I tried by changing the order in which linker objects are specified. But no luck. Any idea why this would be the case?

感谢您的帮助!

推荐答案

Python 3 does not have PyString_AsString any more; the Python 3 str correspond to Python 2 unicode objects; the names of the functions for handling str in Python 3 are PyUnicode_-prefixed in the C-API.

这行:

printf("Python version: %s\n", PyString_AsString(pValue));

可以更改为使用 PyUnicode_AsUTF8 在Python 3上:

could be changed to use PyUnicode_AsUTF8 on Python 3:

#if PY_MAJOR_VERSION >= 3
printf("Python version: %s\n", PyUnicode_AsUTF8(pValue));
#else
printf("Python version: %s\n", PyString_AsString(pValue));
#endif


(不是将NULL传递给printf %s会具有不确定的行为,因此您要检查是否返回了非NULL指针)


(Not that passing NULL to printf %s will have undefined behaviour, so you'd want to check that a non-NULL pointer was returned)

这篇关于将Python嵌入C:链接错误-对PyString_AsString的未定义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆