KobayashiRui
10/14/2017 - 4:49 PM

c++とpythonの連携

cでpython.hをincludeすることでpythonで作成した関数をc側で使用することができる.

日本語でpython3.6について簡単に説明しているところが少なかったためまとめる.

C++とpythonの連携

python側のコードは変更してもC++のコンパイルは必要ない

コンパイル

g++ -I自分のpythonのinclude/python(自分のバージョン) -lpython(自分のバージョン)

ex)pyenvのanacondaの場合

g++ -I/home/ユーザーファイル/.pyenv/versions/anaconda3-4.4.0/include/python3.6m コンパイルファイル -lpython3.6m

参考になるurl

https://docs.python.jp/3/c-api/arg.html#c.PyArg_Parse

https://docs.python.jp/3/c-api/concrete.html

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
import random
def func():
    a = [1,2,3,4,5]
    b = random.choice(a)
    print("hogehoge")
    return b
#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;
}
#include<stdio.h>
#include<Python.h>
#include<string>
#include<iostream>


int main(){
    PyObject *pName,*pModule, *pTmp, *pFunc;
    char *sTmp;
    int data;

    Py_Initialize();
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path,PyUnicode_DecodeFSDefault("."));
    pName = PyUnicode_DecodeFSDefault("py_test1");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if(pModule != NULL){
    pFunc = PyObject_GetAttrString(pModule, "func");

    pTmp = PyObject_CallObject(pFunc, NULL);

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

    return 0;
}