6

だから私はpythonを使って共有C++ライブラリのメソッドを呼び出しています。関数入力として、numpy 2D 配列を short の C++ 2D 配列に変換する際に問題が発生しています。問題を示すおもちゃの例を作成しました。気軽にコンパイルして試してみてください!

Python コード (soexample.py) は次のとおりです。

# 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) は次のとおりです。

#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);    
    }
}

次のコマンドでコンパイルします。

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ですか?

4

1 に答える 1

4

とを使用して、中間変換を支援できctypesます。次の関数は、numpy 配列を C タイプの 2darray に変換し、.c_shortPOINTERshort **

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

func_pyと を変更しCPPClass::funcて、指定された配列の幅と長さの 2 つの追加パラメーターを取ることに注意してください。これにより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
于 2013-06-14T03:40:39.797 に答える