1

I want to do the following.

1. I want to call python from C++.

2. return the value to C++ when I'm done with python.

Compile the c++ file and run the executable.
Then I get an error in the python file.
It was caused by a failure of imort.
When I import the numpy in the python file, I get the following error.
By the way, I confirmed that os and sys can import.

Is the python path wrong?
I tried to be careful with my path, but I don't know...
Please help me.

This post is structured as follows.

◆code
◆Error Description
◆environment
◆Creation of the directory
◆python environment created.
◆compile

#code

◆main.cpp

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

using namespace std;

int main() {
  Py_Initialize();

  PyObject *pName = NULL;
  PyObject *pModule = NULL;
  PyObject *pTmp = NULL;
  PyObject *pFunc = NULL;

  char *sTmp;
  int data;
  const char *pythonFileName =
      "python_code_sample"; // The extension (.py) must be removed.
  const char *functionName =
      "sample_test"; // This function must be included in the script.

  PyObject *sys = PyImport_ImportModule("sys");
  PyObject *path = PyObject_GetAttrString(sys, "path");
  PyList_Append(path,
                PyUnicode_FromString("."));

  PyObject *pythonName = PyUnicode_FromString(pythonFileName);
  PyObject *pythonModule = PyImport_Import(pythonName);
  Py_DECREF(pythonName);

  if (pythonName == NULL) {
    cout << "pName is empty!!!" << endl;
  }

  if (pythonModule == NULL) {
    cout << "pModule is empty!!!" << endl;
  }

  if (pythonModule != NULL) {
    cout << __LINE__ << endl;
    pFunc = PyObject_GetAttrString(pythonModule, functionName);

    pTmp = PyObject_CallObject(pFunc, NULL);

    PyArg_Parse(pTmp, "i", &data);
    printf("%d\n", data);
  }
  Py_Finalize();

  return 0;
}

------------------------

◆python_code_sample.py

#import numpy as np
import random
print("hoge1")

def sample_test():
    a = [1,2,3,4,5]
    print("hige_1")
    #b = random.choice(a)
    print("hoge_2")
    return a[3]
    #return b

if __name__ == "__main__":
    print(sample_test())
#Error Description

◆Error when importing Numpy

/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/bin
/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/__init__.py:140: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
  from . import _distributor_init
pModule is empty!!!
Traceback (most recent call last):
  File "/Users/username/git/python_c_api_sample/python_code_sample.py", line 10, in <module>
    import numpy as np
  File "/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/__init__.py", line 142, in <module>
    from . import core
  File "/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/core/__init__.py", line 50, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.8 from "/Users/username/git/python_c_api_sample/./a.out"
  * The NumPy version is: "1.18.5"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: dlopen(/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so, 2): Symbol not found: _PyBaseObject_Type
  Referenced from: /Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so
  Expected in: flat namespace
 in /Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so


◆Error when importing random

   File "./python_code_sample.py", line 2, in <module>
    import random
  File "/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/random.py", line 41, in <module>
    from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
ImportError: dlopen(/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/lib-dynload/math.cpython-38-darwin.so, 2): Symbol not found: _PyExc_MemoryError
  Referenced from: /Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/lib-dynload/math.cpython-38-darwin.so
  Expected in: flat namespace
 in /Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/lib-dynload/math.cpython-38-darwin.so
# environment
I installed anaconda in pyenv.
I created the environment as follows.
・Anaconda installer is anaconda3-5.0.1
・python3.8.1
・macOS(Catalina version:10.15.4)
・output is g++ -v
 Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
 Apple clang version 11.0.3 (clang-1103.0.32.59)
 Target: x86_64-apple-darwin19.4.0
 Thread model: posix
 InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
# Creation of the directory
mkdir sample_test_python_c_api && cd sample_test_python_c_api
There are two files in the directory: main.cpp and python_code_sample.py.
#python environment created
1. pyenv local anaconda3-5.0.1
2. conda create -n your_env_name python=3.8 anaconda
3. pyenv local anaconda3-5.0.1/envs/your_env_name

export PYTHONHOME=/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name
export PYTHONPATH=$PYTHONHOME/bin
#compile
g++ -fPIC main.cpp $(python3.8-config --cflags --ldflags) -lpython3.8

python3-config --cflags
-I/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/include/python3.8 -I/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/include/python3.8 -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/include -arch x86_64 -I/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/include -arch x86_64

python3.8-config --ldflags
-L/Users/username/.pyenv/versions/anaconda3-5.0.1/envs/your_env_name/lib/python3.8/config-3.8-darwin -ldl -framework CoreFoundation
tanik12
  • 11
  • 3
  • Can you run python script separately? – Farhad Sarvari Jul 21 '20 at 07:12
  • 1
    Thanks for the quick comment! I can confirm that it can be done! – tanik12 Jul 21 '20 at 07:14
  • Please check the version of python and installed numpy . – Farhad Sarvari Jul 21 '20 at 07:16
  • Thanks for the reply! I just checked. pip list | grep numpy -->> numpy 1.18.5, python -V -->> Python 3.8.1 – tanik12 Jul 21 '20 at 07:20
  • I run your program correctly. with python 3.7.7 and numpy 1.19. – Farhad Sarvari Jul 21 '20 at 07:32
  • I used the same version of python and numpy. (Same as you.) But the result was the same, no good. Did you do it in an environment close to mine? Can you tell me the difference between my environment and yours? – tanik12 Jul 21 '20 at 08:04
  • I doubt it's your problem, but you're doing your error checking for `pythonName` _after_ you've used and (probably) freed it – DavidW Jul 21 '20 at 08:05
  • @tanik12 I just use fedora 31 and copy the code that you provided. – Farhad Sarvari Jul 21 '20 at 08:08
  • @DavidW Can you give me a concrete solution? – tanik12 Jul 22 '20 at 02:44
  • @FarhadSarvari Thank you very much. I still haven't been able to solve the problem. Therefore, I will do my best to make it work in my environment. – tanik12 Jul 22 '20 at 02:49
  • @tanik12Oh my dude.Could you please provide more information about your environment sort of things such as OS. – Farhad Sarvari Jul 22 '20 at 05:08
  • @FarhadSarvari anaconda in pyenv, python3.8.1, macOS(Catalina version:10.15.4) If you don't have enough information, please go to me. – tanik12 Jul 22 '20 at 05:36
  • @FarhadSarvari It would be nice if you could check the item again. —> # environment, # python environment created. – tanik12 Jul 22 '20 at 05:36
  • Could you please provide list library dependency from your generated binary file. – Farhad Sarvari Jul 22 '20 at 05:49
  • @FarhadSarvari otool -L binary_file_name --->>> /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1), /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1675.129.0), /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 902.1.0) Please let me know if I'm missing any more information! – tanik12 Jul 22 '20 at 06:31
  • What if you add `#!/usr/bin/env python` at the beginning of your python script? – pptaszni Jul 22 '20 at 11:45
  • Hi @tanik12 Did you find a solution to this problem? – sourabhgupta811 Aug 28 '20 at 10:11

0 Answers0