如何将C数组映射到C#?
我的问题与试图从C#调用用C编写的函数有关。我查看了C库附带的头文件,以了解C dll中存在的函数。我看到的是: C代码(对于名为“LocGetLocations”的函数): 在C#中,我有:如何将C数组映射到C#?,c#,c++,interop,pinvoke,marshalling,C#,C++,Interop,Pinvoke,Marshalling,我的问题与试图从C#调用用C编写的函数有关。我查看了C库附带的头文件,以了解C dll中存在的函数。我看到的是: C代码(对于名为“LocGetLocations”的函数): 在C#中,我有: [DllImport(@"VertexNative\Location.dll")] public static extern uint LocGetLocations(IntPtr findContext, out byte[] locations, uint numberLocations, out i
[DllImport(@"VertexNative\Location.dll")]
public static extern uint LocGetLocations(IntPtr findContext, out byte[] locations, uint numberLocations, out int status);
问题是我不太知道如何处理C#中的pLoc参数。我把它作为一个字节数组,尽管我不确定这是否正确。C库的文档说明该参数是指向句柄数组的指针
我如何从C端获取数组并访问其数据
我在C中给出的示例如下所示:
tLocation lLocation[20];
// other stuff
LocGetLocations(lCtx, lLocation, 20, &lStatus)
任何帮助都将不胜感激 通常,唯一重要的是参数的大小。我记得枚举在C中是整数,所以您可以简单地使用它。或者更好,在C#中重新创建相同的枚举,我认为它会起作用。需要记住的一点是,在处理复杂结构时,需要使用属性来告诉框架所需的成员对齐方式。最后,此签名有效:
[DllImport(@"VertexNative\Location.dll")]
public static extern uint LocGetLocations(IntPtr findContext, [Out] IntPtr[] locations, uint numberLocations, out int status);
我可以这样称呼它(需要一些重构):
谢谢你的帮助 如果它是一个句柄数组,你会希望它是一个
IntPtr
数组。请参阅以获取大量示例。注意,我认为是我使用的“out”关键字让我大吃一惊。移除它让我走得更远。我想这是有道理的,因为数组一开始就是引用类型,不需要通过路由将局部变量分配给方法中的新值。@Nick:您想要的是将[OutAttribute](或只是[Out])添加到IntPtr[]位置。这告诉封送员仅在输出时进行复制,而不是同时进行输入和输出。这将避免发生一个不必要的块复制。但是,向IntPtr[]位置添加数据会导致运行时错误。我编辑了您的答案以显示我的意思。不是out
,[out]
out
是一个参数修饰符[Out]
是一个属性,特别是System.Runtime.InteropServices.OutAttribute
。此属性不是由编译器检查的,而是在运行时由CLR封送处理程序检查的。对marshall来说,这意味着分配非托管内存,从托管内存复制到非托管内存,调用非托管函数,然后从非托管内存复制回托管内存。[In]
和[Out]
属性允许您控制哪些复制发生,因为默认情况下这两个属性都处于启用状态。
[DllImport(@"VertexNative\Location.dll")]
public static extern uint LocGetLocations(IntPtr findContext, [Out] IntPtr[] locations, uint numberLocations, out int status);
IntPtr[] locations = new IntPtr[20];
int status;
// findContext is gotten from another method invocation
uint result = GeoCodesNative.LocGetLocations(findContext, locations, 20, out status);