C到C#PInvoke带有指针的结构

时间:2016-09-20 06:25:48

标签: c# c pointers struct pinvoke

我正在尝试创建一个C#接口,它接收来自外部C DLL的回调。 回调的参数包含指向C结构的指针,它们本身有一个指向不同结构的指针。

回调签名:

typedef application_event_result (*application_event_ptr)(abuffertype* read_buffer, abuffertype* write_buffer);

C:中的缓冲区结构定义

typedef struct {
    uint16 size;   
    uint8* data; 
} anotherbuffertype;

typedef struct {
    anotherbuffertype *buffer; 
    uint16 position; 
} abuffertype;

我知道回调的C#签名应该使用“ref”作为参数的指针类型。但是如何在C#中定义“abuffertype”结构中的指针?

到目前为止,我对C#中的两个结构有这个定义:

    [StructLayout(LayoutKind.Sequential)]
    public struct anotherbuffer
    {
        UInt16 size;
        IntPtr data;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct abuffer
    {
        anotherbuffer buffer;
        UInt16 position;
    } 

但这不起作用。 C#中“abuffer”的内容不是C代码中回调之前的内容。

我是否需要手动解组内部结构指针,若然,怎么做?

1 个答案:

答案 0 :(得分:3)

您将无法获得编组人员的帮助,这通常会导致严重的内存管理问题。但是可以在回调的特定情况下工作,因为它是管理数据的调用C程序。

您必须自己转换数据。将指针声明为IntPtr并使用Marshal.PtrToStructure()来检索数据。

anotherbuffertype.data成员看起来像一个数组,使用Marshal.Copy()将其内容复制到您自己的byte []数组中。如果您不介意unsafe关键字,那么您可以将其声明为byte *并使用data [index]访问元素,从而避免了复制的成本。它不是非常不安全,很容易将索引限制为[0..size]。