c + + calling python program under Linux

Posted by likethegoddess on Sun, 09 Jan 2022 04:45:25 +0100

Run the command under linux according to the command called by windows in the previous article

Libpython3.0 in lib under linux 6m. a. Also include python H in Python 3 6m directory, so you need to modify the command and main CPP #include "Python 3.6m / Python.h"

g++ -I "/root/Anaconda3/envs/tensorflow/include" -L "/root/Anaconda3/envs/tensorflow/lib" main.cpp -lpython3.6m
  1. An error is reported and libpython3 cannot be opened 6m. so. 1.0, reference:

Linux error loading shared library: cannot open shared object file: no such file or directory - stack overflow (stackoverflow.com)

Your library is a dynamic library. You need to tell the operating system where it can find it at run time.

To do this, we need to perform the following simple steps:

  1. If you do not know the location of the library, find the location of the library.
sudo find / -name the_name_of_the_file.so
  1. Check whether the dynamic library path environment variable exists (LD_LIBRARY_PATH)
$ echo $LD_LIBRARY_PATH

If there is nothing to display, add the default path value (or, if you prefer, do not add it)

$ LD_LIBRARY_PATH=/usr/local/lib
  1. We add the required path, export it and try the application.

Note that the path should be the directory where you are. So if it is, it should be: 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. Error report error Py_ Initialize: unable to get the locale encoding, solution:

2.1. reference resources:

Fatal Python error: py in Linux system_ Initialize: unable to get the locale encoding - it reading (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'

Similar questions: command not found:conda

The temporary solution is:

export PATH="/home/[your_name]/anaconda/bin:$PATH"
However, this problem will still occur after the next restart, so we need to acivate ~/.bash_profile

. ~/.bash_profile
#perhaps
source ~/.bash_profile

However, the method subsequently reported an error 3Segmentation fault, so it was abandoned

2.2 reference:

python - is my diagnosis of the cause of "unable to find platform independent library < prefix >" correct? How can I fix it- Stack overflow (stackoverflow.com)

First of all, I am praised for pointing out the way to solve this problem (admittedly very, very cunning), which is due to @ John_ Bollinger. Secondly, I publish this answer only as a solution for those who cannot solve the problem in the right way (see @ John_Bollinger's answer).

There are multiple versions of python on my machine, which are installed locally on my profile. When I define "PYTHONHOME", I do this in my ". bash_profile". I am using the IDE to develop C applications with embedded python code. When I run the application, I get the above error. The first problem is that the function "Py_Initialize()" used to start the python interpreter uses the path stored in PYTHONHOME to find the location of the interpreter. Because I only pass my bash_ The profile defines PYTHONHOME locally, so what happens is that "Py_Initialize()" is not initialized correctly.

The second problem relates to the interpreter lookup module. After correcting the above problems, the interpreter cannot find the basic core module required to run. I still don't know why (I suspect it has something to do with the first question). My solution is to manually specify the path of the module to be used. To get this, run the python interpreter and record the output of the following code:

import sys
print(sys.path)

Take each path output here as part of the path in the C code. The complete work solution is

#include <..../anaconda3/include/python3.7m/Python.h>    

int main(int argc, char **argv, char **envp)
{
    char[] env = "PYTHONHOME=<path to python interpreter>";// location of interpreter.  In my case ..../anaconda3/bin/python3.7m
   putenv(env);  
   Py_SetPath(L"<paths to python modules>");  // output from print(sys.path) above in normal path format; i.e. path1:path2:...
   Py_Initialize();
   // do your stuff
   Py_FinalizeEx();  // close the interpreter and free the memory its using
}

The reason is the problem with the Python interpreter. Because the interpreter in Anaconda3 virtual environment is used, it needs to be specified manually. Modify the code according to the answer idea as follows, but still report an error 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");    //Here is the file name to call
    
    pFunc = PyObject_GetAttrString(pModule, "printHello"); //Here is the name of the function to be called
    PyEval_CallObject(pFunc, NULL);      //Call function
    Py_Finalize();

2.3 PY_ Setpython home to set the interpreter path instead of Py_SetPath, in sys Append the path of Py script to path

    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')");
    //set up. py file location
    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    pModule = PyImport_ImportModule("hello");    //Here is the file name to call
    if (pModule == NULL){
	cout << "don't find the python file!" << endl;
    }
    pFunc = PyObject_GetAttrString(pModule, "printHello"); //Here is the name of the function to be called
    PyEval_CallObject(pFunc, NULL);      //Call function
    Py_Finalize();

This method reports an error 3Segmentation fault for the first time, but it can run normally later.

3. Error Segmentation fault(core dumped) first refer to:

Segmentation fault (core dumped) problem when Python calls dynamic library | yellow warbler Yanbin Blog - software programming practice

Although it is prompted that the core file is "dumped", no core file of dumped is found in the current directory. The reason is the setting of "ulimit". By default, you can see "ulimit -a"

$ ulimit -a
core file size (blocks, -c) 0
......

The core file size is 0, so the "core dumped" above is lying and does not generate a core file. We can use "ulimit - C unlimited" (or set a specific value) to open the dump core option

$ ulimit -c unlimited
$ ulimit -a
core file size (blocks, -c) unlimited

Ulimit is a session parameter, so you have to re execute ulimit -c unlimited when necessary after reconnecting the terminal

Then execute again/ a.out, a core will be generated in the current directory 46951} documents

$ ./a.out
Segmentation fault (core dumped)
$ ls -l core.46951
-rw------- 1 vagrant vagrant 3235840 Aug 24 02:29 core

The next step is to locate the problem with gdb , instead of gdb , use yum or apt , to install it yourself

$ gdb ./a.out core.46951 # GDB executor (python) core file

At this time, go to the gdb console and enter bt to see where the problem is

4. Error report / liblzma so. 5: version `XZ_ 5.1.2alpha' not found (required by /lib64/librpmio.so.3)

reference resources:

CentOS 7 reports an error after installing Anaconda: RPM: / home / WYL / anaconda3 / lib / liblzma so. 5: version `XZ_ 5.1.2alpha 'not found (required by / lib64 / librpmio. So. 3) - squeaky - blog Garden (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

Finally, the 2.3 method is used to modify the code and complete the operation!!!

Topics: Python C++ Linux