2

我有一个用 C 编写的 DLL 文件。我尝试在我的 c# 代码中使用 C DLL。C 程序方法返回 int** 。c 中的 int** 和 c# 中的 int[][] 是一样的吗?

从 c 程序返回值时出现错误。

方法

__declspec(dllexport) int someMethod
    (
        size_t *foo, 
        int **bar
    ) 
    { 
        *foo = 10; 
        **bar = 10; 
    }

我的 C# 代码

[DllImport(@"my.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true, BestFitMapping = true, EntryPoint = "someMethod")]
    public unsafe static extern int someMethod
    (
        out Int16 foo, 
        [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(JaggedArrayMarshaler))] 
        out int[][] bar
    );
4

2 回答 2

1

Cint**和 C#int[][]在概念上相似,但在二进制级别上有所不同:

  • int**是一个指针,指向非托管堆内存中的原始数据。
  • int[][]是对托管数组的托管引用的托管引用;每个指向数组的标题(包含其长度)而不是其原始数据。

我不知道 C# 最容易编组什么。可以SAFEARRAY嵌套吗?如果是这样,它可能很容易映射到 C# 数组。

肯定有效的解决方案是使用 C++/CLI DLL 作为两个代码之间的粘合剂,在返回 C# 之前将其转换int**为 a (这涉及复制指向的数据)。cli::array<cli::array<int>^>^

于 2013-04-15T08:46:23.747 回答
0

假设 C 函数原型是正确的,我认为您应该在 C# 端声明它:

public unsafe static extern int someMethod
(
    out Int16 foo, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, ArraySubType=UnmanagedType.I2)] 
    out int[] bar
);

但是,我担心内存泄漏。我不确定如何释放非托管数组。

于 2013-04-15T11:59:14.533 回答