3

私は Swig 2.0.7 を使用しており、C ライブラリを SWIG でラップして C# からアクセスしようとしています。この C ライブラリは、USB 経由でいくつかのカスタム ハードウェアと通信するため、生の byte[] データをこのライブラリとの間で送受信できる必要があります。私はこの C ライブラリを完全に制御しており、生活を楽にするために必要な方法で変更することができます。

私は Swig ラッパーをうまく使いこなしており、文字列の入出力、およびバイト [] データのライブラリへの送信をうまくコンパイルできたと思います。ただし、データを読み戻そうとすると問題が発生します。

私のパケットは、次のようなカスタム C 構造体になっています。

typedef struct message_in message_in;
struct message_in {
    unsigned char* msg_data;    // Pointer to the data buffer received.
    int data_len;               // The total length of the data buffer received.
    char* dev_path;             // The device that sent us this message.
    message_in*  next;          // Used for the linked list
};

このメッセージを C ライブラリから取得する関数は次のようになります。

message_in* hhcPopIncomingMessage();

次のように、これを .i ファイルでラップしています。

%include "arrays_csharp.i"
// Attempt to use byte[] instead of SWIGTYPE_p_unsigned_char
%apply unsigned char OUTPUT[]  { unsigned char* msg_data }

// Mark this function as owning the memory that it receives, 
//   so that it knows to deallocate
%newobject hhcPopIncomingMessage;

// Mark this structure to use a custom destructor
%extend device_message_in {
    ~device_message_in() {
       hhcFreeMessageIn($self);
    }
}

// Ignore the Linked List member in the data strucutre
%ignore next; 

私が抱えている主な問題は、この構造体を正常に生成しているように見えますが、msg_dataメンバーに対して、byte[] の代わりに自動生成 SWIGTYPE_p_unsigned_char を使用していることです。私が適用した typemap は msg_data アクセサーの戻り値を変更しましたが、まだ内部で SWIGTYPE_p_unsigned_char を使用しており、当然コンパイルされません:

  public byte[] msg_data {
    set {
      hiqusbPINVOKE.message_in_msg_data_set(swigCPtr, value);
    } 
    get {
      IntPtr cPtr = hiqusbPINVOKE.message_in_msg_data_get(swigCPtr);
      SWIGTYPE_p_unsigned_char ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
      return ret;
    } 
  }

(上記はエラーでコンパイルに失敗します:

error CS0029: Cannot implicitly convert type `byte[]' to `System.IntPtr'
error CS0029: Cannot implicitly convert type `SWIGTYPE_p_unsigned_char' to `byte[]'

データ構造からバッファを byte[] として読み取る適切な方法は何ですか?

よろしくお願いします。

編集の更新: 生成するコードを理解したと思います。SWIG にそのコードを生成させる方法がわかりません。

現在生成されているもの:

  public byte[] msg_data {
    set {
      hiqusbPINVOKE.hiq_hid_device_message_in_msg_data_set(swigCPtr, value);
    } 
    get {
      IntPtr cPtr = hiqusbPINVOKE.hiq_hid_device_message_in_msg_data_get(swigCPtr);
      SWIGTYPE_p_unsigned_char ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
      return ret;
    } 
  }

私が生成したいもの:

  public byte[] msg_data {
    // No 'set' member is needed, as this value is only ever read from this structure.
    get {
      int len = this.data_len;
      byte[] managedArray = new byte[len];
  IntPtr cPtr = hiqusbPINVOKE.hiq_hid_device_message_in_msg_data_get(swigCPtr);
      System.Runtime.InteropServices.Marshal.Copy(cPtr, managedArray, 0, len);
      return managedArray;
    } 
  }
4

0 に答える 0