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;
}
但是,数组仍然为空。
有什么建议吗?
我认为在将数组传递给本机代码之前,必须先固定数组。这可以防止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);
}