0

私の目標は、ctypes を使用して、Python 内から個別に作成している C++ ライブラリを呼び出すことです。そこでは、numpy ベクトルをポインターを介して C++ ルーチンに渡します。したがって、Python はメモリを割り当ててアドレスを渡すだけで、C++ ルーチンがデータにアクセスして計算を実行し、結果を返します。

私は ctypes を初めて使用するので、現在、動作するおもちゃの例を徐々に作成しています。C++ コードの作成と、Python ラッパー コードが使用する C extern インターフェイスの作成から始めています。私はまだ Python ラッパー コードに着手していませんが、その側面についてはすでにある程度の経験があります。

これは、コンストラクターと単純な合計関数を含む私の例です。

// foo.cpp //
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Data {
public:
  Data(vector<double>*);
  void PrintTotal(void);
private:
  vector<double>* myContents;
};
Data::Data(vector<double>* input) {
  std::cout << "Entered constructor in C++" << std::endl;
  myContents = input;
}
void Data::PrintTotal(void) {
  double total = 0;
  for (int i=0; i<myContents->size(); i++){
    total += (*myContents)[i];
  }
  std::cout << "Hello, my total is " << total << std::endl;
}

extern "C" {
  Data* Data_new(double (**input)) {return new Data(input);}
  void Print_Total(Data* pData) {pData->PrintTotal();}
}

特に、STL の vector クラスを使用していることに注意してください。これは、以下で説明する問題の一部である可能性があります。クラスDataはデータへのポインタを保持し、データを複製しないという考え方です。

コマンドを使用してこれをコンパイルしようとすると

g++ -c -fPIC foo.cpp -o foo.o

Linux マシンでは、次のエラーが表示されます。

foo.cpp: In function âData* Data_new(double**)â:
foo.cpp:26: error: no matching function for call to âData::Data(double**&)â
foo.cpp:13: note: candidates are: Data::Data(std::vector<double, std::allocator<double> >*)
foo.cpp:6: note:                 Data::Data(const Data&)

これは、私にはかなり明確に思えます: 最後の行から 3 行目 (#26) で Data コンストラクターを呼び出す方法foo.cppが、コードの C++ 部分に記述したコンストラクターと一致しないということです。C++ コードと C extern コードの両方で、入力が double のベクトル/配列へのポインターであると言おうとしています。36 行目で他のオプションを試しましたが、まだコンパイルできません。

vectorC++ 部分でクラス (実際のアルゴリズムをコーディングするときに役立つ) を使用しながら、extern C 部分を作成するにはどうすればよいですか? vectorextern C ではうまく動作しない STL の一部であるため、問題が発生していますか?

前もって感謝します。

4

1 に答える 1

0

まず、あなたの質問に答えましょう。Data_new と同じ引数を取り、入力を std::vector に変換するように、コンストラクターを変更する必要があります。ただし、最初に焦点を当てる必要がある概念的な問題がいくつかあるようです。

  • 配列とベクトルは同等ではありません。入力が配列を指しているが、ベクトルを操作したい場合は、すべての要素を配列からベクトルにコピーする必要があります (または、ベクトル コンストラクターにそれを行うように依頼します)。あなた)。すべての STL コンテナーは、それらに配置された要素のコピーを保持するため、コピーを行う必要があります。

  • 次の 2 つの反復子を使用してベクトルを構築できます。

    myContents(data, data + numberOfElements);

    しかし、これは 2 番目の概念的なポイントをもたらします --- コードの署名には、入力配列の大きさを示すものは何もありません。

  • データでは、ベクトルへのポインターを保持していますが、解放することはありません。これはメモリ リークです。そうは言っても、ベクトルへのポインターではなく、ベクトルを保持する必要があります。

于 2012-08-29T00:29:13.040 に答える