3

私はswigが初めてで、pythonでいくつかのC++ファイルを使用するためにswigラッパーを作成しようとしています。次の C++ クラスがあります。

以下は、変換しようとしているコードのスニペットです。

/*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);
        }
//....
}

今日、swig ドキュメントの助けを借りて、typedefs(uint8_t *) へのポインターを受け入れる example.i ファイルを書き込もうとしましたが、うまくいきませんでした。

以下は、私が試したが動作しない 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 パラメーターごとに詳細を記述する必要がありますか?
4

1 に答える 1

3

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

carrays.i と "%array_class" マクロを使用して、無制限の C 配列をワープできます。例:

%module packet
%include "stdint.i"

%{
    #include "packet.h"
%}

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

%include "packet.h"

次に、Pythonで次のようなものを書くことができます:

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

バッファの寿命が十分であることを確認する必要があることに注意してください.C++コードが認識せずにPythonオブジェクトが解放された場合、未定義の動作が発生します.

マクロも作成するメソッドをuint8_t*使用して、Python でポインター (無制限の配列) をバッファー インスタンスに変換できます。frompointer%array_class

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

必要に応じて追加の Python コードを追加して、バッファー間のほとんどの変換を自動化/非表示にするか、MemoryViewsを使用して C API 側で Python とより緊密に統合することができます。

一般的には、これは C++ であるstd::vectorため、これを使用することをお勧めします。無制限の配列よりも Python 側で使用する方がはるかに優れており、安全性とシンプルさのためにコストは最小限です。

于 2012-05-08T09:12:00.010 に答える