在 C 中嵌入 Python:链接错误 - 未定义对 PyString_AsString 的引用
Embedding Python in C: Error in linking - undefined reference to PyString_AsString
我正在尝试将 python 程序嵌入到 C 程序中。我的 OS 是 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 I 运行 使用以下命令进行编译和链接:
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 does not have PyString_AsString
any more; Python3str
对应Python2unicode
个对象; Python 3 中用于处理 str
的函数名称在 C-API.
中以 PyUnicode_
为前缀
因此这一行:
printf("Python version: %s\n", PyString_AsString(pValue));
可以更改为在 Python 上使用 PyUnicode_AsUTF8
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 指针)
我正在尝试将 python 程序嵌入到 C 程序中。我的 OS 是 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 I 运行 使用以下命令进行编译和链接:
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 does not have PyString_AsString
any more; Python3str
对应Python2unicode
个对象; Python 3 中用于处理 str
的函数名称在 C-API.
PyUnicode_
为前缀
因此这一行:
printf("Python version: %s\n", PyString_AsString(pValue));
可以更改为在 Python 上使用 PyUnicode_AsUTF8
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 指针)