質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

11009閲覧

C++からpythonを呼び出す際に、python側のimport処理が機能しない

taniyan

総合スコア11

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/21 08:56

編集2020/07/22 10:11

次のようなことをしたいと思います。

  1. C++からPythonを呼び出したい。
  2. pythonが終わったらC++に値を返す。(importでエラーが発生しない場合、pythonからの返り値は4)

c++ファイルをコンパイルして実行ファイルを実行します。
実行すると、pythonファイルにエラーが出ます。
原因はpythonファイルで行われているimport文のエラーです。
pythonファイルでnumpyをインポートすると、エラーが出ます。
ちなみに、OSとsysがインポートできることを確認しました。

pythonのパスは間違っているからなのでしょうか?
Pythonのパスには気をつけたつもりでしたが、どうなんでしょう...
ご教授いただけると幸いです。

本投稿は次のように構成にしました

  • ◆コード
  • ◆エラーの説明
  • ◆環境情報
  • ◆コードを動かすために

   -ディレクトリの作成
 -作成されたpython環境
 -コンパイル

コード

◆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())

エラーの説明

◆Numpyをimportした時、下記のエラー内容が出ます。

/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

◆randomをimportした時、下記のエラー内容が出ます。(pythonファイルの2行目を修正してください)

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

◆環境情報

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

◆コードを動かすために

ディレクトリの作成

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環境

  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

cコンパイル

g++ -fPIC main.cpp $(python3.8-config --cflags --ldflags) -lpython3.8 python3.8-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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aokikenichi

2020/07/22 09:48

「原因はpythonファイルで行われているimport文のエラーです。 pythonファイルでnumpyをインポートすると、エラーが出ます。」 とは python python_code_sample.py にて import のエラー Error when importing Numpy が出るということでしょうか
taniyan

2020/07/22 10:14

aokikenichiさん!!!お返事ありがとうございます。 aokikenichiさんの仰る通りで、python python_code_sample.pyにてimportのエラーが出ます。 そのimportした際のエラー内容が◆Error when importing Numpy以下の内容になります。 あと、Error when importing Numpyの箇所を修正したので再度ご確認をよろしくお願いいたします。(すみません…)
guest

回答1

0

ベストアンサー

#解決方法

  1. gccのコンパイルオプションに-rdynamicを付けて下さい
  2. 実行時に環境変数LD_LIBRARY_PATHを$PYTHONHOME/libに設定して下さい

原因

エラーメッセージに

Expected in: flat namespace

と表示されていますのでflat namespacetwo level namespaceが混在していることが原因です。エラーとなったmath.cpython-38-darwin.soのnamespaceを確認すると

terminal

1$ otool -hV math.cpython-38-darwin.so 2Mach header 3 magic cputype cpusubtype caps filetype ncmds sizeofcmds flags 4MH_MAGIC_64 X86_64 ALL 0x00 BUNDLE 16 2240 NOUNDEFS DYLDLINK TWOLEVEL

とtwo level namespaceとなっていますので、この違いによりシンボル名が解決できなかったと思われます。

追記

上記の原因について掘り下げて調べていたところ、そもそもの原因はlibpython3.8がスタティックリンクされていることにあり、その結果、共有ライブラリ(math.cpython-38-darwin.so)が実行ファイルmainに含まれた関数群を読みだせないことが分かりました。-rdynamicオプションにより解決したのは、mainに含まれた関数群を全てシンボルテーブルでグローバル領域へと書き出したためです。

調べたところ、python3.8-config --ldflagsで表示されるディレクトリには、ダイナミックリンクライブラリがありませんでした!したがって下記のようにlibpython3.8.dylibが含まれる$PYTHONHOME/libを優先順位が高くなるように前の方に追記すれば同様に動作するのではないかと思います。

terminal

1g++ -fPIC main.cpp -L$PYTHONHOME/lib $(python3.8-config --cflags --ldflags) -lpython3.8

こちらの方法の方が

  • コンパイル時間が短い
  • mainのサイズも小さい
  • -rdynamicによる副作用もない

と良い事づくめです。

投稿2020/07/22 13:40

編集2020/07/22 15:36
yymmt

総合スコア1615

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taniyan

2020/07/22 14:30 編集

@yymmt 丁寧なご回答にとても感謝をしています。 おかげさまで解決しました!!! 大変助かりました(涙) 本当にありがとうございました。
taniyan

2020/07/23 04:35

@yymmt 追記もありがとうございました。 追記に書いている通りでした!!! とても親切にしてくださり、 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問