C++如何向C#封送不定长数组

在这里记录下如何向C#封送不定长数组。

一、封送常见数据类型定长数组

通常封送平台间通用数据类型(整形、浮点型)只需要在C#代码的变量前加上“[MarshalAs(UnmanagedType.LPArray)]”即可

例如:

 [DllImport("NativeLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
 private static extern int pinvoke([MarshalAs(UnmanagedType.LPArray)]float[] inarray);

C++部分用对应类型数组接收

extern"C" __declspec(dllexport) int pinvoke(float *inarray);

或者将数组转换为IntPtr类型进行封送。

二、封送常见数据类型不定长数组

通常在C#或C++中如果不确定数据长度一般会采用vector或者List来作为参数,但是由于平台间无法直接传递这两种数据,因此需要用一些其他手段来处理。

思路是,C++部分输出数组地址的同时将地址以C#能接收的形式输出,在由C++部分提供释放所分内存的接口。

C++部分

typedef intptr_t        IntPtr;

extern"C" __declspec(dllexport) void pinvoke(IntPtr *handle, int **outArray, int *length)
{
    auto array = new std::vector();
    for (int i = 0; i < 10; i++)
    {
        array->push_back(i);
    }
    *handle = reinterpret_cast(array);
    *outArray = array->data();
    *length = array->size();
}

extern"C" __declspec(dllexport) bool ReleaseObject(IntPtr handle)
{
	std::vector *object = reinterpret_cast*>(handle);
	delete object;
	return true;
}

C#部分

 class SafeHandle : SafeHandleZeroOrMinusOneIsInvalid
        {
            public SafeHandle()
                : base(true)
            {
            }
            protected override bool ReleaseHandle()
            {
                return ReleaseObject(handle);//C++部分提供的接口
            }
        }

[DllImport("NativeLib.dll", CallingConvention = CallingConvention.Cdecl)]
static unsafe extern void pinvoke(out SafeHandle handle, out int* array, out int length);

[DllImport("NativeLib.dll", CallingConvention = CallingConvention.Cdecl)]
static unsafe extern bool ReleaseObject(IntPtr handle);



private unsafe void test()
{
    int* array;
    int length;
    SafeHandle handle;
    pinvoke(out handle, out array, out length);
    for (int i = 0; i < length; i++)
    {
        Console.WriteLine(array[i]);
    }
    handle.Dispose();
}

三、对于结构体数组也适用此种方法。

推荐一本.NET与C++互操作的书籍:「精通.NET互操作」https://www.aliyundrive.com/s/CEyBMxhUggf 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

你可能感兴趣的:(c++,c#)