2017-09-29 31 views
1

私のC++アプリケーションでpython 3(numpyで)を使用しようとしています。 これは、PythonにC++配列を送信し、計算を実行してからC++で結果を取得することを必要とします。 これを行うには、ここで説明したコードに基づいています: https://codereview.stackexchange.com/questions/92266/sending-a-c-array-to-python-numpy-and-back/92353#92353 さらに Sending a C++ array to Python and back (Extending C++ with Numpy)です。Python/numpyをC++に埋め込む

コードレビュー記事の例は基本的には機能しますが、私はPythonとC++スクリプトを修正したときに戻り値に問題があります:Pythonで作成された変数を返そうとすると、計算された計算の代わりに、 私の推測では、オブジェクトはどうにかスコープから外れてしまいますが、私はこの問題を解決できません。

は私がmymodule.pyというファイルに次のPythonスクリプトを使用します。

import numpy 

def array_tutorial(a): 
    print("array_tutorial - python") 
    print(a) 
    print("") 
    firstRow = a[0,:] 
    #beta = numpy.array([[10,20,30],[10,20,30],[10,20,30]]) 
    #firstRow = beta[0,:] 
    return firstRow 

def myfunction(): 
    beta = numpy.array([[1,2,3],[1,2,3],[1,2,3]]) 
    print("myfunction - python") 
    print(beta) 
    print("") 
    firstRow = beta[0,:] 
    return firstRow 

私のC++コードは、ファイルnumpy_cpp.cppである受け入れの若干変更と単純化されたバージョンがありますコードレビューポストに答えてください。私はPythonスクリプトが発見されたことを確認する

setenv("PYTHONPATH", ".", 0); 

を追加する必要がありました受け入れ答えに比べ

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 

#include <Python.h> 
#include "numpy/arrayobject.h" 

int main(int argc, char* argv[]) 
{ 
    setenv("PYTHONPATH", ".", 0); 

    Py_Initialize(); 
    import_array(); 

    // Build the 2D array in C++ 
    const int SIZE = 3; 
    npy_intp dims[2]{SIZE, SIZE}; 
    const int ND = 2; 
    long double(*c_arr)[SIZE]{ new long double[SIZE][SIZE] }; 

    for (int i = 0; i < SIZE; i++){ 
     for (int j = 0; j < SIZE; j++){ 
      c_arr[i][j] = i + j;} 
    } 

    // Convert it to a NumPy array. 
    PyObject *pArray = PyArray_SimpleNewFromData(ND, dims, NPY_LONGDOUBLE, reinterpret_cast<void*>(c_arr)); 

    // import mymodule 
    const char *module_name = "mymodule"; 
    PyObject *pName = PyUnicode_FromString(module_name); 
    PyObject *pModule = PyImport_Import(pName); 
    Py_DECREF(pName); 

    // import function 
    const char *func_name = "array_tutorial"; 
    PyObject *pFunc = PyObject_GetAttrString(pModule, func_name); 
    PyObject *pReturn = PyObject_CallFunctionObjArgs(pFunc, pArray, NULL); 
    PyArrayObject *np_ret = reinterpret_cast<PyArrayObject*>(pReturn); 

    // Convert back to C++ array and print. 
    int len = PyArray_SHAPE(np_ret)[0]; 
    long double* c_out; 
    c_out = reinterpret_cast<long double*>(PyArray_DATA(np_ret)); 
    std::cout << "Printing output array - C++" << std::endl; 
    for (int i = 0; i < len; i++){ 
     std::cout << c_out[i] << ' '; 
    } 
    std::cout << std::endl << std::endl; 


    // import function without arguments 
    const char *func_name2 = "myfunction"; 
    PyObject *pFunc2 = PyObject_GetAttrString(pModule, func_name2); 
    PyObject *pReturn2 = PyObject_CallFunctionObjArgs(pFunc2, NULL); 
    PyArrayObject *np_ret2 = reinterpret_cast<PyArrayObject*>(pReturn2); 

    // convert back to C++ array and print 
    int len2 = PyArray_SHAPE(np_ret2)[0]; 
    long double* c_out2; 
    c_out2 = reinterpret_cast<long double*>(PyArray_DATA(np_ret2)); 
    std::cout << "Printing output array 2 - C++" << std::endl; 
    for (int i = 0; i < len2; i++){ 
     std::cout << c_out2[i] << ' '; 
    } 
    std::cout << std::endl << std::endl; 

    Py_Finalize(); 
    return 0; 
} 

、私は入力引数としていない関数「MyFunctionを」のための第2の機能の呼び出しを追加しましたエラー処理のいくつかを削除しました。

私はUbuntuの16.10で午前と(import_arrayずつの警告()を除いて罰金行くもの)コンパイルとリンクする

g++ -Wall numpy_cpp.cpp -I/usr/include/python3.5m/ -lpython3.5m 

を使用しています。しかし私は、プログラムを実行するのpython 3.

を対象に以下のコンソール出力を与えています:

array_tutorial - python 
[[ 0.0 1.0 2.0] 
[ 1.0 2.0 3.0] 
[ 2.0 3.0 4.0]] 

Printing output array - C++ 
0 1 2 

myfunction - python 
[[1 2 3] 
[1 2 3] 
[1 2 3]] 

Printing output array 2 - C++ 
nan nan nan 

それはPythonが設定されたnumpyの配列の最初の行を返す私のトラブルを与える最後の出力でありますPythonスクリプトで Pythonのprintステートメントからは、numpyの配列は問題ありませんが、C++に参照されると、横向きになります。

array_tutorial関数のreturn文の上にある2行のコメントを外すと、最初の関数呼び出しと同じ(失望した)結果が得られます。

私の質問は、オブジェクトが(おそらく)スコープ外に出ることなくC++で正しい値を取得する方法ですか?

長い投稿をお詫び申し上げます。ご協力いただきありがとうございます。


EDIT: Pythonでnumpyのアレイの下lomereiterにより指摘したように、心内データ型を維持設定されるべきです。 これは問題を解決します。受け取った配列のデータ型を出力し、宣言された配列のデータ型は次のようになり指定 より良いPythonスクリプト:あなたがPythonコードで配列を作成するときに

import numpy 

def array_tutorial(a): 
    print("array_tutorial - python") 
    print(a) 
    print(numpy.dtype(a[0,0])) 
    print("") 
    firstRow = a[0,:] 
    #beta = numpy.array([[10,20,30],[10,20,30],[10,20,30]],dtype=numpy.float128) 
    #firstRow = beta[0,:] 
    return firstRow 

def myfunction(): 
    beta = numpy.array([[1,2,3],[1,2,3],[1,2,3]],dtype=numpy.float128) 
    print("myfunction - python") 
    print(beta) 
    print("") 
    firstRow = beta[0,:] 
    return firstRow 
+0

このエラーは '' 'main.cpp:26:21:error:expected ';'宣言の最後に npy_intp dims [2] {SIZE、SIZE}; '' ' – sAguinaga

答えて

1

あなたはDTYPEを指定する必要があります。 dtypeがint64(64ビットプラットフォーム)であると推定されている間に、C++コードでlong double型にキャストしています

+0

本当にありがとう、本当にありがとう。正しいdtypeは "numpy.float128"でした(私の場合) – user3456032

関連する問題