C 到 C# PInvoke 带指针的结构
C to C# PInvoke with structs with pointers
我正在尝试创建一个 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代码中回调前的内容。
我是否需要手动解组内部结构指针,如果需要,如何解组?
您不会得到编组器的帮助,这通常会导致严重的内存管理问题。但可以在回调的特定情况下工作,因为它是管理数据的调用 C 程序。
您必须自己转换数据。将指针声明为 IntPtr
并使用 Marshal.PtrToStructure()
检索数据。
anotherbuffertype.data成员看起来像一个数组,使用Marshal.Copy()
将其内容复制到你自己的byte[]数组中。如果您不介意 unsafe
关键字,那么您可以将其声明为 byte* 并使用 data[index] 访问元素,避免复制成本。将索引限制在 [0..size].
并不是很不安全,很容易
我正在尝试创建一个 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代码中回调前的内容。
我是否需要手动解组内部结构指针,如果需要,如何解组?
您不会得到编组器的帮助,这通常会导致严重的内存管理问题。但可以在回调的特定情况下工作,因为它是管理数据的调用 C 程序。
您必须自己转换数据。将指针声明为 IntPtr
并使用 Marshal.PtrToStructure()
检索数据。
anotherbuffertype.data成员看起来像一个数组,使用Marshal.Copy()
将其内容复制到你自己的byte[]数组中。如果您不介意 unsafe
关键字,那么您可以将其声明为 byte* 并使用 data[index] 访问元素,避免复制成本。将索引限制在 [0..size].