C#中没有保留C++函数中的数组更改

本文关键字:数组 C++ 有保留 函数 | 更新日期: 2023-09-27 18:29:54

我有一个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;
}

但是,数组仍然为空。

有什么建议吗?

C#中没有保留C++函数中的数组更改

我认为在将数组传递给本机代码之前,必须先固定数组。这可以防止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 );
}

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

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

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

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

发现此链接非常有用:

C#:使用字符**参数调用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);
        }