C到C#P用指针结构调用 [英] C to C# PInvoke with structs with pointers

查看:75
本文介绍了C到C#P用指针结构调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个C#接口,该接口接收来自外部C DLL的回调. 回调的参数包含指向C结构的指针,而C结构本身也具有指向其他结构的指针.

I'm trying to create a C# interface which receives a callback from an external C DLL. The callback's parameters contain pointers to C structs, which themselves have a pointer to a different struct.

回调签名:

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

C中的缓冲区结构定义:

The buffer struct definitions in C:

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

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

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

I know that the C# signature of the callback should use "ref" for the pointer type of the parameter. But how can the pointer inside the "abuffertype" struct be defined in C#?

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

So far I have this definition of the two structs in C#:

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

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

但这不起作用. C#中缓冲"的内容不是C代码中回调之前的内容.

But that doesn't work. The contents of "abuffer" in C# is not what was there before the callback in the C code.

我需要手动解组内部struct指针吗?如果是,怎么做?

Do I need to unmarshal the internal struct pointer manually, and if so, how?

推荐答案

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

You will not get help from the marshaller, this normally causes a major memory management problem. But can work in the specific case of a callback since it is the calling C program that manages the data.

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

You have to convert the data yourself. Declare the pointers as IntPtr and use Marshal.PtrToStructure() to retrieve the data.

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

The anotherbuffertype.data member looks like an array, use Marshal.Copy() to copy its content into your own byte[] array. If you don't mind the unsafe keyword then you can keep it declared as byte* and access the elements with data[index], avoids the cost of the copy. It is not very unsafe, pretty easy to keep index constrained to [0..size).

这篇关于C到C#P用指针结构调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆