C到C#P用指针结构调用 [英] C to C# PInvoke with structs with pointers
问题描述
我正在尝试创建一个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屋!