如何将 C 数组映射到 C#?

Posted

技术标签:

【中文标题】如何将 C 数组映射到 C#?【英文标题】:How to map a C array to C#? 【发布时间】:2010-12-08 16:43:21 【问题描述】:

我的问题与尝试从 C# 调用用 C 编写的函数有关。我查看了 C 库附带的头文件,以了解 C dll 中存在的函数。这是我看到的:

C 代码(用于名为“LocGetLocations”的函数):

typedef enum 
    eLocNoError,
    eLocInvalidCriteria,
    eLocNoMatch, 
    eLocNoMoreLocations,
    eLocConnectionError, 
    eLocContextError,
    eLocMemoryError
 tLocGetStatus; 

typedef void *tLocFindCtx;

typedef void *tLocation;    

PREFIX unsigned int POSTFIX LocGetLocations
(
    tLocFindCtx pCtx, 
    tLocation *pLoc,
    unsigned int pNumLocations,
    tLocGetStatus *pStatus
);

在 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)

任何帮助将不胜感激!

【问题讨论】:

如果它是句柄数组,您需要将其设为 IntPtr 数组。 见pinvoke.net/index.aspx 有很多例子。 【参考方案1】:

通常,唯一重要的是参数的大小。我记得枚举是 C 中的整数,所以你可以简单地使用它。或者更好的是,在 C# 中重新创建相同的枚举,我认为它会起作用。需要记住的一件事是,在处理复杂结构时,需要使用属性来告诉框架所需的成员对齐方式。

【讨论】:

【参考方案2】:

最后,这个签名有效:

[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);

感谢您的帮助!

【讨论】:

注意,我认为是我使用了“out”关键字让我感到困惑。删除它让我走得更远。我猜这是有道理的,因为数组是一开始的引用类型,不需要将局部变量分配给方法中的新值。 @Nick:您想要的是将 [OutAttribute](或只是 [Out])添加到 IntPtr[] 位置。这告诉编组器只在输出时复制,而不是在输入和输出时复制。这样可以避免发生不必要的块副本。 添加到 IntPtr[] 位置会给我一个运行时错误。 我编辑了您的答案以说明我的意思。不是out[Out] out 是一个参数修饰符。 [Out] 是一个属性,具体来说是System.Runtime.InteropServices.OutAttribute。这个属性不是由编译器检查的,而是在运行时由 CLR 编组器检查的。编组意味着分配非托管内存,从托管内存复制到非托管,调用非托管函数,然后从非托管复制回托管。 [In][Out] 属性允许您控制发生的复制,因为默认情况下两者都是打开的。

以上是关于如何将 C 数组映射到 C#?的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 对象映射到 C# 类属性数组

如何将 C 指针编组到 C# 结构数组

在 C# 中将字典映射到数组的最快方法

如何将二维数组从 C# 传递到 C++?

c#如何将结构的引用添加到数组或列表?

如何使用jq将json项目值映射到兄弟数组