Passing a byte array from Unity C# into a C++ library method
Solution 1
You have to change your method definition to take an IntPtr. This is the C# way to define a pointer to non-managed memory. To create this pointer use Marshal.AllocHGlobal()
and then copy the data to it using 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
. After this the memory is no longer valid so the C++ library can't use it any more. 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.
Solution 2
works for me:
in unity:
[DllImport ("dllplugin")]
public static extern void Method (byte[] bytes);
in c++ Plugin
#define EXPORT_API __declspec(dllexport)
extern "C" void EXPORT_API Method(unsigned char* bytes)
Ghopper21
Slowing converting from Stack Overflow lurker into a contributing member. SOreadytohelp
Updated on June 05, 2022Comments
-
Ghopper21 almost 2 years
I have a C++ library method that I'd like to call from a Unity C# script.
I understand there are three key steps. First, to declare the C++ methods to be
extern "C"
. Second, to use[DllImport('foobar')]
before the corresponding C# extern method declaration. Third, to name the library file with the lib prefix (e.g.libfoobar.so
) and place it in the Unity plugins folder.So far so good -- if I'm only passing simple parameter types like
int
from C# into C++. However, to pass abyte[]
parameter, I will need to account for the different ways C# and C++ handle memory and pointers. 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? -
Rajesh over 6 yearsI am passing the byte array from unity to c++ plugin like this way, It works fine but untiy sending the 17 bytes otherside(C++) receive 4 bytes only.what is the reason?Please Help
-
Admin over 4 years@Rajesh Same problem here. Passing 4096 bytes from C# to C++, but on the C++ end the array is only ever 8 bytes according to
sizeof(bytes)
. -
Admin over 4 yearsAdditionally, changing it to a unsigned
char*
rather than achar
just makes sizeof 8 while the length of the array is 1. -
Pierre Wargnier over 4 yearsI know this is an old post but in C++, sizeof(bytes) will only give you the size of the pointer and not the size of the data it points to, see the first answer on this post : stackoverflow.com/questions/399003/… . If you want to do it this way, you will need to also pass the length of the C# bytes array.
-
Pierre Wargnier over 4 yearsI edited the answer for the function to also have the length of the array as parameter. Note that in this case, we do not need element size since we know it is one byte per element. On the c++ side, the start of the buffer will be bytes and the end of the buffer will be bytes + length.