SWIG:如何包装byte []结构成员

时间:2012-11-12 22:55:35

标签: c# c mono swig

我正在使用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;
    } 
  }

0 个答案:

没有答案