2013-06-14 29 views
6

私は共有のC++ライブラリのメソッドを呼び出すためにpythonを使用しています。私はnumpyの2D配列を関数入力としてshortのC++ 2D配列に変換する際に問題が発生しています。私は問題を呈する玩具の例を作りました。コンパイルして試してみてください!私は次のコマンドを使用してコンパイル2D numpy配列をC++ short **に変換しますか?

#include <iostream> 

using namespace std; 

class CPPClass 
{ 
    public: 
    CPPClass(){} 

    void func(unsigned short **array) 
    { 
     cout << array[0][0] << endl; 
    } 
}; 

// For use with python: 
extern "C" { 
    CPPClass* CPPClass_py(){ return new CPPClass(); } 
    void func_py(CPPClass* myClass, unsigned short **array) 
    {  
     myClass->func(array);  
    } 
} 

ここ
# Python imports 
from ctypes import CDLL 
import numpy as np 

# Open shared CPP library: 
cpplib=CDLL('./libsoexample.so') 
cppobj = cpplib.CPPClass_py() 

# Stuck on converting to short**? 
array = np.array([[1,2,3],[1,2,3]]) 
cpplib.func_py(cppobj,array) 

は、C++ライブラリ(soexample.cpp)である:ここ

は、Pythonコード(soexample.py)であります

g++ -fPIC -Wall -Wextra -shared -o libsoexample.so soexample.cpp 

私がPythonファイルを実行すると、次のエラーが表示されます。

>> python soexample.py 
Traceback (most recent call last): 
    File "soexample.py", line 13, in <module> 
    cpplib.func_py(cppobj,array) 
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to  convert parameter 2 

この不都合な点を正しく修正する方法を教えてください。TypeError

+1

私はCの短いint型は16ビットであると信じています。一方、デフォルトのnumpy intは、通常32ビットです。配列を 'array = np.array([[1,2,3]、[1,2,3]]、dtype = np.uint16)'として作成し、何が起こるかを見ることができます。 – Jaime

答えて

4

​​のc_shortPOINTERを使用して、中間変換に役立てることができます。以下の関数は、numpy配列をC型2d配列に変換し、short **を期待するC関数に渡すことができます。

def c_short_2darr(numpy_arr): 
    c_short_p = POINTER(c_short) 
    arr = (c_short_p * len(numpy_arr))() 
    for i in range(len(numpy_arr)): 
    arr[i] = (c_short * len(numpy_arr[i]))() 
    for j in range(len(numpy_arr[i])): 
     arr[i][j] = numpy_arr[i][j] 
    return arr 

注、Iは2つの追加パラメータ、所与のアレイの幅と長さを取ることfunc_pyCPPClass::func修飾。これにより、CPPClass::funcは、配列の要素のすべてをプリントアウトすることができます:定義されたヘルパー関数で

// ... 
void CPPClass::func(unsigned short **array, size_t w, size_t h) 
{ 
    for(size_t i = 0; i < w; ++i) 
    { 
     for(size_t j = 0; j < h; ++j) 
      cout << array[i][j] << ", "; 
     cout << '\n'; 
    } 
} 
// ... 
void func_py(CPPClass *myClass, 
      unsigned short **array, 
      size_t w, size_t h) 
{ 
    myClass->func(array, w, h); 
} 

を、次のように動作するはずです:

>>> arr = numpy.array([ [1,2,3], [4,5,6] ]) 
>>> arr 
array([[1, 2, 3], 
     [4, 5, 6]]) 
>>> cpplib.func_py(cppobj, c_short_2darr(arr), 2, 3) 
1, 2, 3, 
4, 5, 6, 
0 
+0

ありがとう!それは完璧に働いた。私はあなたがここで私を助けることができるかもしれない別の同様の質問があります: http://stackoverflow.com/questions/17138054/return-c-double-to-python – dillerj

関連する問題