我有一个C ++库方法,我想从Unity C#脚本调用。
据我所知,有三个关键步骤。首先,将C ++方法声明为extern "C"
。其次,在相应的C#extern方法声明之前使用[DllImport('foobar')]
。第三,使用lib前缀(例如libfoobar.so
)命名库文件,并将其放在Unity插件文件夹中。
到目前为止一直很好 - 如果我只是将简单的参数类型如C#中的int
传递给C ++。但是,要传递byte[]
参数,我需要考虑C#和C ++处理内存和指针的不同方式。我还没有找到一个如何做到这一点的明确例子。
我的问题:如何将byte[]
从Unity C#脚本传递到外部C ++库方法?
答案 0 :(得分:4)
适合我:
统一:
[DllImport ("dllplugin")]
public static extern void Method (byte[] bytes);
在c ++插件中
#define EXPORT_API __declspec(dllexport)
extern "C" void EXPORT_API Method(unsigned char* bytes)
答案 1 :(得分:3)
您必须更改方法定义才能使用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
调用,并确保在库不再需要访问该内存后删除该内存。