2012-05-08 6 views
3

私はswigに非常に新しいです。私はPythonでいくつかのC++ファイルを使用するためにswigラッパーを作成しようとしています。私は次のC++クラスを持っています。PythonへのC++(ポインタ)のswigラッパーの作成

次は私が変換しようとしているコードの抜粋です:

/*packet_buffer.h*/ 
class CPacketBuffer { 
public: 
    // construct based on given buffer, data is not copied 
    CPacketBuffer(uint8_t* data, uint32_t length) { 
     mpBuffer = data; 
     mLength = length; 
     mHead = 0; 
     mTail = length; 
    } 
    uint8_t* GetBuffer() { 
     return (mpBuffer + mHead); 
    } 
    void Add(const uint8_t* data, uint32_t length) { 
      if ((mTail + length) > mLength) { 
      length = (mLength - mTail); 
     } 
//.... 
} 

今日は一日中(* uint8_tを)のtypedefへのポインタを受け入れるだろうexample.iファイルを書き込もうとしてきましたswigのドキュメントの助けを借りて、私は失敗しました。

以下は私が試したpacket_buffer.iファイルですが、動作しません。

%module packet_buffer 
%include typemaps.i 
%apply unsigned char* {uint8_t*}; 
%apply unit8_t *INPUT {uint8_t *data}; 



%{ 
    #define SWIG_FILE_WITH_INIT 
    #include "../include/packet_buffer.h" 
%} 
%include "../include/packet_buffer.h" 
  1. にはどうすればいいのtypedefへのポインタを取るメンバ関数のためのSWIGのコードを書くのですか?
  2. コード全体で使用できる共通の%applyを書くことができますか、またはそれぞれのINPUT、OUTPUTパラメータに固有の記述をしなければなりませんか?

答えて

3

私がこれを正しく理解していれば、直面している問題はポインタではなく、潜在的に無限の配列であることです。

あなたはwarp an unbounded C array例えば、carrays.iおよびマクロ "array_class%" を使用することができます:あなた」

a = packet.buffer(10000000) 
p = packet.CPacketBuffer(a.cast(), 10000000) 

注:

%module packet 
%include "stdint.i" 

%{ 
    #include "packet.h" 
%} 

%include "carrays.i" 
%array_class(uint8_t, buffer); 

%include "packet.h" 

はその後、Pythonでのあなたのような何かを書くことが可能になりますバッファの寿命を十分に確保する必要があります.C++コードが認識されずにPythonオブジェクトが解放されると、未定義の動作に終わります。

あなたは%array_classマクロも作成frompointer方法、例えば使用Pythonでインスタンスをバッファリングするuint8_t*ポインタ(無限アレイ)に変換することができる:

r = packet.GetBuffer() 
buf = packet.buffer_frompointer(r) 

あなたはadd additional Python code /自動化することができるとの間の変換の大部分を隠します必要ならバッファーを使うか、MemoryViewsを使ってC API側でPythonとより緊密に統合することができます。

これはC++なので、std::vectorを使用することをお勧めしますが、Python側では無制限の配列よりもずっと使いやすく、コストは安全性とシンプルさという点で最低です。

+0

返信いただきありがとうございます。これらは低レベルのパケットハンドラであるため、STLを使用することはできません。これはエラーなく機能しましたが、私はこのような関数をどのように変換するのか分かりませんでしたuint8_t * GetBuffer(){ return(mpBuffer + mHead); }、ここでメンバーへのポインタを返しますか? –

+0

@ GuruGovindan - 別の方法を実行するための構文を使ってアップデートを追加しました。個人的にはまだ 'std :: vector'を除外するのは間違いだと思いますが、それはあなたの欠陥率を減らす可能性があり、違いが生じる現実的なベンチマークを作ることができれば驚いています。 (特にPython側からのもの)。 – Flexo

+0

awoodlandのアップデートをありがとう、残念ながら私はデザインを変更する意思決定をすることはできません。しかし、私は間違いなくベクトルの使用を提案します。 –

関連する問題