c# - 如何在 C# 互操作调用中从 C# 实例化数组中的 C 取回数据?

标签 c# c arrays interop boolean

我想在 C# 中为 boolean 数组实例化内存,并使用互操作将其传递给 C 库函数。然后 C 函数应该用数据(结果)填充数组,以便数据可以传回 C# 并在那里使用。由于数组是引用类型,并且我为数组显式设置了 [In, Out] 编码属性,所以我认为这很容易。但显然不是。 :-( 下面是一些说明问题的测试代码(尽可能简单)。

在 C 中,我会这样调用:

extern "C" __declspec(dllexport) int __stdcall TestFillArray(bool *resultMaterials, int materialLength);


__declspec(dllexport) int __stdcall TestFillArray(bool *resultMaterials, int materialLength)
{
    resultMaterials[0] = true; 
    resultMaterials[1] = true; 
    return materialLength;
}

我使用以下声明从 C# 调用此函数:

[DllImport("FrontAuction2.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern int TestFillArray([MarshalAs(UnmanagedType.LPArray, SizeConst = 2), In, Out] bool[] resultMaterial, int materialLength);

然后在我的 C# 测试方法中我有:

var resultMaterials = new bool[2];
var res = TestFillArray(resultMaterials, 2);

当我检查结果时,我得到 res=2 和 resultMaterials[0] = true,以及 resultMaterials[1] = false。 IE。 res 值和第一个数组元素都是正确的,但第二个不是。所以看起来 boolean 数据没有正确编码(除非我遗漏了一些明显的东西)。

我猜也可以声明一个 IntPtr 而不是一个数组,并成功地将这两个元素编码为正确的结果。但是,由于我希望在 C# 中将数组分配到内存中,所以我不确定该怎么做。

非常感谢这方面的帮助。我有点被困在这里。 :(


更新:我猜这是因为 boolean 值只有 1 个字节长,而 C# 代码没有获取此信息。那么如何指定呢?

最佳答案

使用

[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeConst = 2), In, Out]

应该告诉框架将数组混搭为 1 字节 bool 的数组。另一种选择是改用 4 字节 BOOL。有关详细信息,请参阅 UnmanagedType enum .

关于c# - 如何在 C# 互操作调用中从 C# 实例化数组中的 C 取回数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6599324/

相关文章:

c# - 测量 Asp.Net MVC 应用程序请求/响应时间的准确方法

c# - ASP.NET Identity Custom PasswordValidator 检查用户名

C# Winform( Entity Framework )- 将数据绑定(bind) DataGridView 或 BindingSource 转换为 DataTable

c++ - 通过按空格键结束键盘输入数据,而不是输入键 c/c++

Javascript - 无法遍历带有图像的对象数组

c# - RDLC 报表直接打印到 POS 打印机时为什么报表会缩小

c - gdb 无法访问内存地址错误

java - C 和 JNI 数组列表

c++ - 为什么 ISO C++ 禁止返回数组?

javascript - 导出数组中元素的所有可能组合