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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

C++

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

Q&A

解決済

2回答

6679閲覧

C++ から Python 実行について

Reach

総合スコア735

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

C++

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

1グッド

2クリップ

投稿2018/05/12 23:24

編集2018/05/13 02:16

c++から Pythonの関数を実行したいのです
(できれば Pythonをインストールしていない環境でも実行できるように)

とりあえず、Web検索で見つけた
Python.h をインクルードし、PyObject_CallObject()関数を使用した
プログラムをコンパイルしました
しかし、実行すると

Fatal Python error: Py_Initialize: unable to load the file system codec
Import Error: No module named 'encodings'

のエラーが出ました
そこで Pythonのlibフォルダ内のファイルを EXEファイルのあるフォルダーにコピーし、
実行可能となりましたが もっと スマートな 解決方法は ありませんでしょうか?

また 上記方法は Pythonが ない環境で 動作させることは 可能でしょうか?

追記:
環境
python 3.5.3 (Version)
Windows 7 64bit

試したコード

c++

1#include<stdio.h> 2#include<Python.h> 3#include<string> 4#include<iostream> 5 6 7int main(){ 8 PyObject *pName,*pModule, *pTmp, *pFunc; 9 PyObject *pArgs, *pValue; 10 double res_data; 11 double a = 10.5; 12 13 //最初に必ず入れる 14 Py_Initialize(); 15 16 //カレントディレクトリを探す範囲にいれる------------------------- 17 PyObject *sys = PyImport_ImportModule("sys"); 18 PyObject *path = PyObject_GetAttrString(sys, "path"); 19 PyList_Append(path,PyUnicode_DecodeFSDefault(".")); 20 //--------------------------------------------------------------- 21 22 //探すファイルをしてい------------------------------------------- 23 pName = PyUnicode_DecodeFSDefault("py_test2"); 24 pModule = PyImport_Import(pName); 25 Py_DECREF(pName); 26 //--------------------------------------------------------------- 27 28 //タプルの作成 ----------------------------------------------- 29 pArgs = PyTuple_New(1);//タプルを新しく作成する 30 pValue = PyFloat_FromDouble(a);//pValueにaの数値を設定 31 PyTuple_SetItem(pArgs,0,pValue);//タプルの0の位置にpValueを設定 32 //--------------------------------------------------------------- 33 34 if(pModule != NULL){ 35 36 //pFuncに今回呼び出す関数を設定する(今回はfunc) 37 pFunc = PyObject_GetAttrString(pModule, "func"); 38 39 //pFuncを引数を与える(pArgsはタプルでなければならない) 40 pTmp = PyObject_CallObject(pFunc, pArgs); 41 42 //関数を実行 d:double型を受け取る 43 PyArg_Parse(pTmp, "d", &res_data); 44 printf("%f\n",res_data); 45 } 46 //最後に必ず入れる 47 Py_Finalize(); 48 49 return 0; 50}

Python

1#py_test2.py 2 3import random 4def func(data): 5 print("hogehoge") 6 a = data 7 print(a) 8 list_data = [14,2,3.5,28] 9 list_data.append(a) 10 b = random.choice(list_data) 11 return b
YouheiSakurai👍を押しています

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

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

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

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

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

raccy

2018/05/13 01:58

Pythonのバージョンはいくつでしょうか?また、Pythonを実行するコードはどのようになっていますでしょうか?
guest

回答2

0

ベストアンサー

C/C++からPythonを実行する場合、少なくともPython本体のDLLが必要になります。Windows版Python3.6であれば、Python36.dllがそれにあたります。しかし、このDLLにはPythonのビルドインオブジェクトや関数しかありません。Libにあるようなimportして使う各ライブラリは使えないということです。しかし、もっと深刻なことがあります。それは、Py_Initialize()が内部でencodingsライブラリを使っていると言うことです(ライブラリのロード等でファイルシステムの名前をエンコードするために使っていると推測されます)。そのため、DLLだけでは、つまりライブラリのファイルがなければ、Py_Initialize()すら出来ないというのがこの現象です。

この現象を解消するにはDLLだけではなく標準ライブラリもセットにして、exeと同じファイルに置く必要があります。しかし何を置いて良いのかよくわからないとお思いでしょう。そんなときのためにライブラリがセットになって組込に使える一式が用意されています。

Python Releases for Windows | Python.org

通常の"Windows x86|x86-64 web-based|executable installer"というファイルの他に"windows x86|x86-64 embeddable zip file"というのがあるのがわかると思います。このファイルをダウンロードして、展開したファイルの中身全てをexeと同じ場所に置きます。はい、これで完了です。x86(32bit)版とx86-64(64bit)版の二つが用意されていることに注意してください。これはexeのアーキテクチャに合わせる必要があります。

これは組み込み用のファイル一式です。Python本体である"Python3x.dll"の他、標準ライブラリがセットになっています。コンパイルが必要なものはコンパイル済みであり、コンパイルが不要なPythonで出来たファイルは"python3x.zip"の中にまとめて入っています。"python3x._pth"にはどこからライブラリを探すのかという情報がのっており、そこには"python3x.zip"と"."(カレントディレクトリ)が記載されています。"python3x.zip"のなかには"encodings"のライブラリが入っていますので、エラーは回避できるようになるでしょう。

参考: 3.6 Python 埋め込みのための配布 — Python 3.6.5 ドキュメント

配布物のサイズをコンパクトにしたいというのであれば、コンパイル済みライブラリ(pydファイル)や"python3x.zip"を展開して不要な物を削っていくしかありません。しかし、依存関係やPython内部のソースを確認しながらの作業となりますので、苦労の割にはあまり効果がないとかも知れません。(そもそも一番大きいPython3x.dllは本体なので削除は出来ませんし)

投稿2018/05/13 02:55

raccy

総合スコア21737

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

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

Reach

2018/05/13 04:19

大変ありがとうございます embedded zip file および Python3x.dll は (他の人に) 配布することは 可能なのでしょうか?
Reach

2018/05/13 04:41

有益な情報 ありがとうございました
guest

0

一般的には、無理と、思ったのですが、

PyObject_CallObject()

なんてのがあるのですねる。
調べてみたところ、Pythonの初期化などを最初におこなっていますね。
という事は、Pythonが無い環境で動かすのはやはり無理でしょう。

Pyhtonコードのコンパイルで調べると色々とありますが、大抵はバイトコンパイルなので、Python環境が必要。 Cコードにコンパイルする方法もあるようですが、そこまでして使う必要があるか? と言うのと、どんな場合でも可能か言うと、ちょっと疑問がありそうです。

投稿2018/05/13 01:20

pepperleaf

総合スコア6385

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問