簡體   English   中英

在C中嵌入Python:鏈接時出錯 - 對PyString_AsString的未定義引用

[英]Embedding Python in C: Error in linking - undefined reference to PyString_AsString

我試圖在C程序中嵌入一個python程序。 我的操作系統是Ubuntu 14.04

我嘗試在相同的C代碼庫(作為單獨的應用程序)中嵌入python 2.7和python 3.4解釋器。 編譯和鏈接在嵌入python 2.7時有用,但不適用於python 3.4。 它在鏈接器階段失敗。

這是我的C代碼(只是一個例子不是真正的代碼)

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我使用以下命令運行編譯和鏈接:

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標志編譯它時,它失敗了:

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

我嘗試通過更改指定鏈接器對象的順序。 但沒有運氣。 知道為什么會這樣嗎?

謝謝您的幫助!!

Python 3不再有PyString_AsString ; Python 3 str對應Python 2 unicode對象; 的功能處理的名稱str在Python 3是PyUnicode_的C-API在-prefixed。

這樣一行:

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

可以更改為在Python 3上使用PyUnicode_AsUTF8

#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指針)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM