tag - Pasar una matriz de bytes de Unity C#a un método de biblioteca C++
unity gameobject[] (2)
Tengo un método de biblioteca C ++ que me gustaría llamar desde un script de Unity C #.
Entiendo que hay tres pasos clave. Primero, declarar que los métodos de C ++ son extern "C"
. Segundo, para usar [DllImport(''foobar'')]
antes de la declaración del método externo C # correspondiente. En tercer lugar, para nombrar el archivo de la biblioteca con el prefijo lib (por ejemplo, libfoobar.so
) y colocarlo en la carpeta de complementos de Unity.
Hasta aquí todo bien, si solo estoy pasando tipos de parámetros simples como int
de C # a C ++. Sin embargo, para pasar un parámetro byte[]
, tendré que dar cuenta de las diferentes formas en que C # y C ++ manejan la memoria y los punteros. No he podido encontrar un ejemplo definitivo de cómo hacer esto.
Mi pregunta: ¿cómo pasar un byte[]
de un script de Unity C # a un método de biblioteca C ++ externo?
Tienes que cambiar la definición de tu método para tomar un IntPtr. Esta es la forma C # para definir un puntero a la memoria no administrada. Para crear este puntero use Marshal.AllocHGlobal()
y luego Marshal.AllocHGlobal()
los datos usando Marshal.Copy()
.
Ejemplo (no probado):
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);
}
}
}
Tenga en cuenta que debe liberar la memoria no administrada manualmente utilizando Marshal.FreeHGlobal
. Después de esto, la memoria ya no es válida, por lo que la biblioteca C ++ ya no puede usarla. Si necesita acceder al conjunto en un momento posterior, elimine la llamada de FreeHGlobal
y asegúrese de eliminar la memoria una vez que la biblioteca ya no necesite acceder a ella.
funciona para mi:
en unidad
[DllImport ("dllplugin")]
public static extern void Method (byte[] bytes);
en el complemento c ++
#define EXPORT_API __declspec(dllexport)
extern "C" void EXPORT_API Method(unsigned char* bytes)