我正在使用Swig 2.0.7并尝试使用SWIG包装C库以从C#访问它。这个C库通过USB与一些自定义硬件通信,因此我需要能够向/从该库发送/接收原始byte []数据。我可以完全控制这个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 []。我应用的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;
}
}