将一个字节数组从Unity C#传递到C++库方法中

Passing a byte array from Unity C# into a C++ library method

本文关键字:C++ 方法 Unity 一个 数组 字节数 字节      更新时间:2023-10-16

我有一个C++库方法,我想从Unity C#脚本中调用它。

我知道有三个关键步骤。首先,将C++方法声明为extern "C"。其次,在相应的C#外部方法声明之前使用[DllImport('foobar')]。第三,用lib前缀(例如libfoobar.so)命名库文件,并将其放在Unity插件文件夹中。

到目前为止一切都很好——如果我只是将简单的参数类型(如int)从C#传递到C++中。然而,要传递byte[]参数,我需要考虑C#和C++处理内存和指针的不同方式。我还没有找到一个明确的例子来说明应该如何做到这一点。

我的问题是:如何将Unity C#脚本中的byte[]传递到外部C++库方法中?

您必须更改方法定义以获取IntPtr。这是定义指向非托管内存的指针的C#方法。要创建此指针,请使用Marshal.AllocHGlobal(),然后使用Marshal.Copy()将数据复制到其中。

示例(未测试):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Assets.Scripts
{
    public class DLLCall
    {
        [DllImport("thedll")]
        public static extern void TheCall(IntPtr byteArray, int size);
        public void PerformCall(byte[] data)
        {
            IntPtr unmanagedArray = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, unmanagedArray, data.Length);
            TheCall(unmanagedArray, data.Length);
            Marshal.FreeHGlobal(unmanagedArray);
        }
    }
}

请注意,必须使用Marshal.FreeHGlobal手动释放非托管内存。在此之后,内存不再有效,因此C++库无法再使用它。如果以后需要访问数组,请删除FreeHGlobal调用,并确保在库不再需要访问内存后删除内存。

适用于我:

统一:

[DllImport ("dllplugin")]
public static extern void Method (byte[] bytes);

在c++插件中

#define EXPORT_API __declspec(dllexport)
extern "C" void EXPORT_API Method(unsigned char* bytes)