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

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

ただいまの
回答率

90.62%

  • Python 3.x

    5850questions

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

  • C++

    3324questions

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

  • VC++

    136questions

    VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 457

Beginner_ABC

score 4

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 

試したコード

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


int main(){
    PyObject *pName,*pModule, *pTmp, *pFunc;
    PyObject *pArgs, *pValue;
    double res_data;
    double a = 10.5;

    //最初に必ず入れる
    Py_Initialize();

    //カレントディレクトリを探す範囲にいれる-------------------------
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path,PyUnicode_DecodeFSDefault("."));
    //---------------------------------------------------------------

    //探すファイルをしてい-------------------------------------------
    pName = PyUnicode_DecodeFSDefault("py_test2");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    //---------------------------------------------------------------

    //タプルの作成    -----------------------------------------------
    pArgs = PyTuple_New(1);//タプルを新しく作成する
    pValue = PyFloat_FromDouble(a);//pValueにaの数値を設定
    PyTuple_SetItem(pArgs,0,pValue);//タプルの0の位置にpValueを設定
    //---------------------------------------------------------------

    if(pModule != NULL){

    //pFuncに今回呼び出す関数を設定する(今回はfunc)
    pFunc = PyObject_GetAttrString(pModule, "func");

    //pFuncを引数を与える(pArgsはタプルでなければならない)
    pTmp = PyObject_CallObject(pFunc, pArgs);

    //関数を実行 d:double型を受け取る
    PyArg_Parse(pTmp, "d", &res_data);
    printf("%f\n",res_data);
    }
    //最後に必ず入れる
    Py_Finalize();

    return 0;
}
#py_test2.py

import random
def func(data):
    print("hogehoge")
    a = data
    print(a)
    list_data = [14,2,3.5,28]
    list_data.append(a)
    b = random.choice(list_data)
    return b
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • raccy

    2018/05/13 10:58

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

    キャンセル

回答 2

checkベストアンサー

+4

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 13:19

    大変ありがとうございます

    embedded zip file および Python3x.dll は (他の人に) 配布することは 可能なのでしょうか?

    キャンセル

  • 2018/05/13 13:35

    無償・有償や商用利用の有無にかかわらず、自由に自分の作品に組み込んで配布することが出来ます。詳しくは下記を参考にしてください。
    https://docs.python.jp/3/faq/general.html#are-there-copyright-restrictions-on-the-use-of-python

    キャンセル

  • 2018/05/13 13:41

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

    キャンセル

+1

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

PyObject_CallObject()

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    beautiful soup4 ダウンロード

    サイトに行って、beautiful soup4をダウンロードして解凍してからpythonのlibに入れました。 beautifulsoup4-4.4.1.tar どうしたら

  • 解決済

    【Python】標準入出力におけるリスト格納について

    前提・実現したいこと ここに質問したいことを詳細に書いてください (例)PHP(CakePHP)で●●なシステムを作っています。 ■■な機能を実装中に以下のエラーメッセージが

  • 解決済

    list内のtuple内の要素を元にして、listを処理したい

    お世話になっております。ややこしいタイトルで申し訳ありません。 今回お伺いしたいのは、pythonのリストに内包しているtupleの要素を元にリストの処理を行えるかについてです。

  • 解決済

    python 標準入力

    初歩的な質問で申し訳ありません pythonで 1234 5678 9999 のように入力したとき 配列 e[0][0]=1 e[0][1]=2 e[0][2]=3 ... e[2

  • 解決済

    文字列を比較して配列に格納できない

    ans配列の要素の文字列の最初の文字がlinesの要素の最初の文字と一致するならlinesの2番目の要素('A'/'B'/'C'/'D')をline_alpha配列に格納する、とい

  • 解決済

    pythonのスライスについて

    a = b[:,0] このようなコードがあったとき、どのようなことがおこなわれますか? bはこのコードがなりたつ何かだとすると なにだったら成り立ちますか? すみません、間

  • 解決済

    opencv python 画像処理

    # -*- coding: utf-8 -*- import cv2 import numpy as np # フレーム差分の計算 def frame_sub(src1, src

  • 解決済

    TypeError: 'list' object is not callable

    python manage.py test polls とコマンドを打つと、TypeError: 'list' object is not callableというエラーが出ました。

同じタグがついた質問を見る

  • Python 3.x

    5850questions

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

  • C++

    3324questions

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

  • VC++

    136questions

    VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。