0
点赞
收藏
分享

微信扫一扫

Linux下c++调用python程序

捡历史的小木板 2022-01-09 阅读 82

按照上篇windows下调用的在linux下运行命令

其中linux下lib中为libpython3.6m.a,同时include中Python.h在python3.6m目录下,因此需要修改命令和main.cpp中#include "python3.6m/Python.h"

g++ -I "/root/Anaconda3/envs/tensorflow/include" -L "/root/Anaconda3/envs/tensorflow/lib" main.cpp -lpython3.6m
  1. 报错打不开libpython3.6m.so.1.0,参考:

加载共享库时出现 Linux 错误:无法打开共享对象文件:没有此类文件或目录 - 堆栈溢出 (stackoverflow.com)

您的库是一个动态库。您需要告诉操作系统它在运行时可以找到它的位置。

为此,我们需要执行以下简单步骤:

  1. 如果您不知道库的位置,请查找库的位置。
sudo find / -name the_name_of_the_file.so
  1. 检查动态库路径环境变量是否存在(LD_LIBRARY_PATH)
$ echo $LD_LIBRARY_PATH

如果没有任何要显示的内容,请添加默认路径值(或者,如果您愿意,则不添加)

$ LD_LIBRARY_PATH=/usr/local/lib
  1. 我们添加所需的路径,将其导出并试用该应用程序。

请注意,路径应为 所在的目录。所以如果是在它应该是:path.so.somethingpath.so.something/my_library/path.so.something

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/my_library/
$ export LD_LIBRARY_PATH
$ ./my_app

2. 报错Python.error Py_initialize: Unable to get the locale encoding,解决思路:

2.1.参考:

Linux 系統中 Fatal Python error: Py_Initialize: Unable to get the locale encoding - IT閱讀 (itread01.com)

Xlx@lx-PC:~$ python
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'

類似問題:command not found:conda

暫時性的解決方法是:

export PATH="/home/[your_name]/anaconda/bin:$PATH"
但是下一次重啟之後,還是會出現這個問題,所以我們要acivate ~/.bash_profile

. ~/.bash_profile
#或者
source ~/.bash_profile

但该方法后续报错3Segmentation fault,遂放弃

2.2参考:

python - 我对"找不到独立于平台的库<prefix>"的原因的诊断是否正确,我该如何修复它?- 堆栈溢出 (stackoverflow.com)

原因是Python解释器的问题,因为采用Anaconda3虚拟环境中的解释器,所以需要手动指定,根据答案思路修改代码如下,但还是报错3Segmentation Fault

    #include <stdlib.h>
    char env[] = "PYTHONHOME=/root/anaconda3/envs/nudt/bin/python3.6m";
    putenv(env);  
    
    // location of interpreter.  In my case ..../anaconda3/bin/python3.7m
    Py_SetPath(L"/root/anaconda3/envs/nudt/lib/python36.zip:"
                "/root/anaconda3/envs/nudt/lib/python3.6:"
                "/root/anaconda3/envs/nudt/lib/python3.6/lib-dynload:"
                "/root/anaconda3/envs/nudt/lib/python3.6/site-packages"); 
    //Py_SetPythonHome(L"/root/anaconda3/envs/nudt")
    //Py_SetProgramName(L"/root/anaconda3/envs/nudt/bin/python3.6m")
    Py_Initialize();
    PyErr_Print();
    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    pModule = PyImport_ImportModule("hello");    //这里是要调用的文件名
    
    pFunc = PyObject_GetAttrString(pModule, "printHello"); //这里是要调用的函数名
    PyEval_CallObject(pFunc, NULL);      //调用函数
    Py_Finalize();

2.3采用Py_SetPythonHome来设置解释器路径,而不是Py_SetPath,后在sys.path中追加py脚本所在路径

    wchar_t env[] = L"/root/anaconda3/envs/nudt/";
    wchar_t program[] = L"/root/anaconda3/envs/nudt/bin/python3.6";
    Py_SetPythonHome(env);
    Py_SetProgramName(program);

    Py_Initialize();
    PyRun_SimpleString("print('hello world!')");
    //printf("python home: %s\n", Py_GetPythonHome());
    //printf("program name: %s\n", Py_GetProgramName());
    //printf("get path: %s\n", Py_GetPath());
    //printf("get prefix: %s\n", Py_GetPrefix());
    //printf("get exec prefix: %s\n", Py_GetExecPrefix());
    //printf("get prog full path: %s\n", Py_GetProgramFullPath());

    PyRun_SimpleString("import sys");
    printf("path: ");
    PyRun_SimpleString("print(sys.path)");
    PyRun_SimpleString("sys.path.append(r'/home/zhouzj/cproject')");
    //设置.py文件所在位置
    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    pModule = PyImport_ImportModule("hello");    //这里是要调用的文件名
    if (pModule == NULL){
	cout << "don't find the python file!" << endl;
    }
    pFunc = PyObject_GetAttrString(pModule, "printHello"); //这里是要调用的函数名
    PyEval_CallObject(pFunc, NULL);      //调用函数
    Py_Finalize();

该方法第一次运行时报错3Segmentation fault,但后续可正常运行。

3. 报错Segmentation fault(core dumped) 首先参考:

Python 调用动态库时 Segmentation fault (core dumped) 问题 | 隔叶黄莺 Yanbin Blog - 软件编程实践

core file size 为 0, 所以上面的 core dumped 是在撒谎,并没有生成 core 文件,我们可以用 ulimit -c unlimited(或设置一个具体数值) 打开 dump core 的选项

ulimit 是会话参数,所以重新连接终端后需要时又得重新执行 ulimit -c unlimited

这时再次执行./a.out, 在当前目录中就会产生一个 core.46951 文件

接下来要做的就是用 gdb 定位出问题的地方,没有 gdb 的用 yum 或 apt 自行安装

这时进到 gdb 的控制台,输入 bt, 就能看到哪里出问题了

4. 报错/liblzma.so.5: version `XZ_5.1.2alpha' not found (required by /lib64/librpmio.so.3)

参考:

centos7安装anaconda之后报错:rpm: /home/wyl/anaconda3/lib/liblzma.so.5: version `XZ_5.1.2alpha' not found (required by /lib64/librpmio.so.3) - 吱吱了了 - 博客园 (cnblogs.com)

cd /data/anaconda3/lib/
unlink liblzma.so.5
cd /lib64/
cp liblzma.so.5.2.2 /data/anaconda3/lib/
ln -s -f liblzma.so.5.2.2 liblzma.so.5

最终采用2.3方法修改代码完成了运行!!!

举报

相关推荐

0 条评论