简体   繁体   English

将Unity C#中的字节数组传递给C ++库方法

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

I have a C++ library method that I'd like to call from a Unity C# script. 我有一个C ++库方法,我想从Unity C#脚本调用。

I understand there are three key steps. 我知道有三个关键步骤。 First, to declare the C++ methods to be extern "C" . 首先,将C ++方法声明为extern "C" Second, to use [DllImport('foobar')] before the corresponding C# extern method declaration. 其次,在相应的C#extern方法声明之前使用[DllImport('foobar')] Third, to name the library file with the lib prefix (eg libfoobar.so ) and place it in the Unity plugins folder. 第三,使用lib前缀(例如libfoobar.so )命名库文件,并将其放在Unity插件文件夹中。

So far so good -- if I'm only passing simple parameter types like int from C# into C++. 到目前为止一切都很好 - 如果我只是将简单的参数类型(如C#中的int传递给C ++。 However, to pass a byte[] parameter, I will need to account for the different ways C# and C++ handle memory and pointers. 但是,要传递byte[]参数,我需要考虑C#和C ++处理内存和指针的不同方式。 I haven't been able to find a definitive example of how to this should be done. 我无法找到一个如何做到这一点的明确例子。

My question: how to pass a byte[] from a Unity C# script into a external C++ library method? 我的问题:如何将一个byte[]从Unity C#脚本传递到外部C ++库方法?

You have to change your method definition to take an IntPtr. 您必须更改方法定义以获取IntPtr。 This is the C# way to define a pointer to non-managed memory. 这是定义指向非托管内存的指针的C#方式。 To create this pointer use Marshal.AllocHGlobal() and then copy the data to it using Marshal.Copy() . 为了创建这个指针使用Marshal.AllocHGlobal()然后使用数据复制到Marshal.Copy()

Example (not tested): 示例(未测试):

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);
        }

    }
}

Notice that you have to free the unmanaged memory manually by using Marshal.FreeHGlobal . 请注意,您必须使用Marshal.FreeHGlobal手动释放非托管内存。 After this the memory is no longer valid so the C++ library can't use it any more. 在此之后,内存不再有效,因此C ++库不能再使用它了。 If it needs to access the array at a later point remove the FreeHGlobal call and make sure to delete the memory after the library no longer requires access to it. 如果稍后需要访问该阵列,请删除FreeHGlobal调用,并确保在库不再需要访问它之后删除该内存。

works for me: 适合我:

in unity: 团结一致:

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

in c++ Plugin 在c ++插件中

#define EXPORT_API __declspec(dllexport)

extern "C" void EXPORT_API Method(unsigned char* bytes)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM