Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将C数组映射到C#?_C#_C++_Interop_Pinvoke_Marshalling - Fatal编程技术网

如何将C数组映射到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

我的问题与试图从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 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);