2

我有一个调用 C++ 函数的 C# 代码。

C++ 函数应该填充一个用指针传递的缓冲区。但是,数组返回空。

进口声明为:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(char[] arr);

代码经过简化并输入一些硬编码值后如下所示:

C# 中的代码:

char[] arr= new char[10];
ret = LogicInterface.FillArr(arr);

C++ 代码:

bool FillArr(char* arr)
{
       int length=10;
       for(int i = 0; i < length; i++) 
       {
              arr[i] = 3; //replaced with some hard coded value
       }
       return true;
}

但是,数组仍然是空的。

有什么建议么?

4

3 回答 3

1

我相信您必须先固定数组,然后再将其传递给您的本机代码。这可以防止 GC 在您在 C++ 中访问托管数组时在内存中移动它。

所以你可以使用:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr( char* arr );

接着:

char[] arr = new char[ 10 ];

fixed (char* pinned = arr )
{
    ret = LogicInterface.FillArr( pinned );
}

请注意,我实际上并没有编译和运行它,但它应该会给你一些关于如何继续的想法。

于 2012-04-04T10:16:44.553 回答
1

只要 C++ 中的代码在返回之前不缓存它,就不需要固定数组。

在您的情况下,您需要通过引用传递数组,以便将其视为输出参数。

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(ref char[] arr);`
于 2012-04-04T10:22:13.907 回答
-1

发现此链接非常有用:

C#:使用 char** 参数调用 C++ DLL

最终代码如下所示:

    [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
    static extern bool FillArr([MarshalAs(UnmanagedType.LPStr, ArraySubType = UnmanagedType.LPStr)] StringBuilder args);

        static void Main(string[] args)
        {
            StringBuilder arr = new StringBuilder(9);
            bool res = FillArr(arr);
        }
于 2012-04-04T11:38:45.967 回答