gpt4 book ai didi

c# - 当 C# 调用 c++ 函数时,是否可以在调用的 c++ 函数中初始化数组并返回到 C#?

转载 作者:行者123 更新时间:2023-11-30 05:21:05 25 4
gpt4 key购买 nike

C++ 函数知道数组的大小并且必须创建它。

C++代码:

__declspec(dllexport) int getlog(int* &data)
{
data = new int[5];

for (int i = 0; i < 5; i++)
{
data[i] = i;
}

return 0;
}

和 C#:

    [DllImport(@"myDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int getlog(int[] data);

    int[] arr = null;
getlog(arr);

我看到 this但它没有帮助

最佳答案

在 C# 方面:

[DllImport(@"myDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int getlog([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out int[] data,
out int length);

在 C++ 方面:

#include <Objbase.h>

extern "C" __declspec(dllexport) int getlog(int** data, int * length)
{
*length = 5;
int sizeInBytes = sizeof(int) * (*length);
*data = static_cast<int*>(CoTaskMemAlloc(sizeInBytes ));

for (int i = 0; i < 5; i++)
{
(*data)[i] = i;
}

return 0;
}

CoTaskMemAlloc 将使 CLR 能够在内存不再可用时负责释放内存。有关更多信息,请参阅 "Memory Management with the Interop Marshaler" :

The runtime always uses the CoTaskMemFree method to free memory. If the memory you are working with was not allocated with the CoTaskMemAlloc method, you must use an IntPtr and free the memory manually using the appropriate method.

上述方法适用于 .NET 4.0 及更高版本。对于 .NET 3.5,它由于对 unmanaged arrays 的有限支持而失败:

The array being controlled cannot be passed as ref or out parameters. Likewise, the parameter containing the size of the array must be passed by value (the SizeParamIndex field cannot refer to a ref or out parameter)

要克服这个问题并在 C# 端获取数组,请使用以下签名:

[DllImport(@"MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int getlog(out IntPtr data, out int length);

当您对数据有 IntPtr 时,可以将内容复制到托管数组:

int length;
IntPtr data;
getlog(out data, out length);
int[] managedArr = new int[length];
Marshal.Copy(data, managedArr, 0, length);

您也可以在不处理的情况下处理此类数组的内容。要使用此方法,请在项目设置中启用“允许不安全代码”:

int length;
IntPtr data;
getlog(out data, out length);

unsafe
{
int* intArray = (int*)data.ToPointer();
for (int i = 0; i < length; i++)
{
Console.WriteLine(intArray[i]);
}
}

关于c# - 当 C# 调用 c++ 函数时,是否可以在调用的 c++ 函数中初始化数组并返回到 C#?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40398951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com