私は 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;
}
}