gpt4 book ai didi

c++ - 使用 CMake 导入错误编译带有嵌入式 Python 的 C++

转载 作者:太空狗 更新时间:2023-10-29 21:45:20 24 4
gpt4 key购买 nike

我正在尝试在使用 CMake 编译的 C++ 项目中包含一个 python 文件。

首先,我使用这两个文件独立完成此操作:

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

int main(int argc, char *argv[])
{
setenv("PYTHONPATH", ".", 0);
char hostname[] = "localhost";
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
Py_Initialize();
pName = PyString_FromString("GetHostname");
pModule = PyImport_Import(pName);
Py_DECREF(pName);

if(pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "GetHostname");

if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(1);
pValue = PyString_FromString(hostname);
PyTuple_SetItem(pArgs, 0, pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("The IP address is %s\n", PyString_AsString(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr, "Call Failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function\n");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load file\n");
return 1;
}
Py_Finalize();
return 0;
}

import socket

def GetHostname(hostname):
addr = socket.gethostbyname(hostname)
return addr

当我编译时使用

g++ $(python-config --cflags) -o test $(python-config --ldflags) ./test.cpp

来自 how to link python static library with my c++ program一切正常。

但这包含在使用 CMake 编译的项目中,我一定是做错了什么,因为编译后我得到了

Traceback (most recent call last):
File "/src/GetHostname.py", line 1, in <module>
import socket
File "/usr/lib64/python2.6/socket.py", line 46, in <module>
import _socket
ImportError: /usr/lib64/python2.6/lib-dynload/_socketmodule.so: undefined symbol: PyExc_ValueError

我在 CMakeLists.txt 中添加了这些行

find_package( PythonInterp REQUIRED )
find_package( PythonLibs REQUIRED )
include_directories ( ${PYTHON_INCLUDE_DIRS} )
add_library (GetHostname MODULE GetHostname.cc)
target_link_libraries(GetHostname ${PYTHON_LIBRARIES})
CONFIGURE_FILE(${PATH_TO_SOURCE}GetHostname.py ${PATH_TO_BUILD}GetHostname.py COPYONLY)

基于此线程 Python.h: No such file or directory

一切都可以编译,但 python 模块由于错误而无法加载。我没有在 CMake 中正确链接 python 库吗?

欢迎任何可以解释失败原因的想法。

使用 Python 2.6

我知道这可以在 C++ 中完成,但这不是我需要包含的唯一 python 模块,因此用 C++ 重写它不是我正在寻找的答案。我也知道现在本地主机的 IP 地址是已知的,这只是为了测试目的。

最佳答案

所以我终于自己找到了答案。

问题是,当在 CMake 中链接时,与 python 库的链接仅在本地加载 (RTLD_LOCAL),这意味着实际的 python 脚本未与 python 库链接,仅与 C++ 链接。

要解决此问题,只需在 C++ 代码中首先加载具有全局符号解析的 python 库。

dlopen("libpython2.6.so.1.0", RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL);

这是一个快速而肮脏的修复程序,因为它特定于 python2.6,您应该根据机器上安装的版本在 CMake 中定义变量来使其具有可移植性。

您必须导入 dlfcn 才能使用 dlopen:

#include <dlfcn.h>

关于c++ - 使用 CMake 导入错误编译带有嵌入式 Python 的 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17842915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com