我正在使用 Swig 2.0.7 并尝试使用 SWIG 包装 C 库以从 C# 访问它。这个 C 库通过 USB 与一些自定义硬件通信,因此我需要能够向/从这个库发送/接收原始字节 [] 数据。我可以完全控制这个 C 库,并且可以以任何我需要的方式对其进行修改,以使我的生活更轻松。
我的 Swig 包装器已经取得了很好的进展,我认为我已经得到了它可以很好地编译输入/输出字符串,以及将 byte[] 数据发送到库中。但是,我在尝试读取数据时遇到了问题。
我的数据包采用自定义 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
成员来说,它使用的是自动生成的 SWIGTYPE_p_unsigned_char,而不是 byte[]。我应用的类型映射改变了 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[]'
从我的数据结构中读取缓冲区作为字节 [] 的正确方法是什么?
在此先感谢您的帮助!
编辑更新: 我想我想出了我希望它生成的代码——现在我只是不知道如何让 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;
}
}