将字节数组从C ++非托管dll传递到C#unity

我试图将字节数组从我的非托管c ++ dll返回到c#unity。 非常感谢您提前花时间来帮助> <我在团结中对DLL非常新,所以我非常困惑2种语言甚至可以合作。

CPP

问题出在这里,我已经完成了我的计算,但是我很难找到一种方法将数据格式返回给c#。

目前,字节数组包含颜色代码,例如RGBA(223,124,23,255,212,143,234,255)并重复

#include "WebcamDLL.h" #include  extern "C" { int adjustBrightnesss(unsigned char* bytes, int sizeOfArray) { std::vector myvector; int alphaP = 0; for (int i = 0; i < sizeOfArray; i++) { switch (alphaP) { case 0: case 1: case 2: myvector[i] = bytes[i] / 2; alphaP++; break; case 3: alphaP = 0; break; } } return bytes; } } 

头文件

 #ifdef TESTFUNCDLL_EXPORT #define TESTFUNCDLL_API __declspec(dllexport) #else #define TESTFUNCDLL_API __declspec(dllimport) #endif extern "C" { TESTFUNCDLL_API int adjustBrightnesss(unsigned char* bytes, int sizeOfArray); } 

C#文件

 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Runtime.InteropServices; // Needed for custom DLL using System; public class WebcamManager : MonoBehaviour { private RawImage ri; // Gets the RawImage component from script parent private WebCamTexture wct; // Object to hold the WebCamTexture add-on private AspectRatioFitter arf; // Ensures RawImage object has same scaling as Webcam private Color32[] pixels; // Keeps the pixels from webcamtexture Texture2D tex; // A placeholder for the texture2D [DllImport("WebcamBrightness", EntryPoint = "adjustBrightness")] public static extern int adjustBrightness(byte bytes, int b); void Start() { newBrightness = 1; // Default 1, if 0 will make image go super bright arf = GetComponent(); // Gets the component AspectRatioFitter in script parent ri = GetComponent(); // Gets the component RawImage in script parent wct = new WebCamTexture(Screen.width, Screen.height); // Creates a new WebCamTexture in wct with the width and height of the current screen wct.Play(); // plays webcam //adjustBrightness(wct.GetPixels32()); } // Update is called once per frame void Update() { float videoRatio = (float)wct.width / (float)wct.height; // Ensures that the scaling is the same as the webcam arf.aspectRatio = videoRatio; // applies webcam scaling to rawimage tex = new Texture2D(wct.width, wct.height, TextureFormat.ARGB32, false); // pass texture2D tex the information of webcamtexture height, width, ARGB32 (32 bit with alpha) and no mipmaps pixels = wct.GetPixels32(); // After getting the bytes, I wanna save it back to color32 or atleast an array format. tex.SetPixels32(pixels); tex.Apply(); // Sets texture of rawimage from canvas to be web camera view ri.texture = tex; } } 

编写CPP文件

 #include "WebcamDLL.h" #include  extern "C" { unsigned char* adjustBrightness(unsigned char* bytes, int sizeOfArray) { int alphaP = 0; for (int i = 0; i < sizeOfArray; i++) { switch (alphaP) { case 0: case 1: case 2: bytes[i] = bytes[i] / 2; alphaP++; break; case 3: alphaP = 0; break; } } return bytes; } int freeMem(unsigned char* arrayPtr) { delete[] arrayPtr; return 0; } } 

编辑的头文件

 #ifdef TESTFUNCDLL_EXPORT #define TESTFUNCDLL_API __declspec(dllexport) #else #define TESTFUNCDLL_API __declspec(dllimport) #endif extern "C" { TESTFUNCDLL_API unsigned char* adjustBrightness(unsigned char* bytes, int sizeOfArray); TESTFUNCDLL_API int freeMem(unsigned char* arrayPtr); } 

编写C#文件

 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Runtime.InteropServices; // Needed for custom DLL using System; public class WebcamManager : MonoBehaviour { private RawImage ri; // Gets the RawImage component from script parent private WebCamTexture wct; // Object to hold the WebCamTexture add-on private AspectRatioFitter arf; // Ensures RawImage object has same scaling as Webcam private Color32[] pixels; // Keeps the pixels from webcamtexture Texture2D tex; // A placeholder for the texture2D public RawImage ri2; float timer; [DllImport("WebcamBrightness", EntryPoint = "adjustBrightness", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr adjustBrightness(byte[] bytes, int b); [DllImport("WebcamBrightness", EntryPoint = "freeMem", CallingConvention = CallingConvention.Cdecl)] public static extern int freeMem(IntPtr ptr); [SerializeField] int newBrightness; void Start() { newBrightness = 1; // Default 1, if 0 will make image go super bright arf = GetComponent(); // Gets the component AspectRatioFitter in script parent ri = GetComponent(); // Gets the component RawImage in script parent wct = new WebCamTexture(Screen.width, Screen.height); // Creates a new WebCamTexture in wct with the width and height of the current screen wct.Play(); // plays webcam float videoRatio = (float)wct.width / (float)wct.height; // Ensures that the scaling is the same as the webcam arf.aspectRatio = videoRatio; // applies webcam scaling to rawimage tex = new Texture2D(wct.width, wct.height, TextureFormat.ARGB32, false); // pass texture2D tex the information of webcamtexture height, width, ARGB32 (32 bit with alpha) and no mipmaps } // Update is called once per frame void Update() { //timer += Time.deltaTime; pixels = wct.GetPixels32(); IntPtr returnedPtr = adjustBrightness(Color32ArrayToByteArray(pixels), Color32ArrayToByteArray(pixels).Length); byte[] returnedResult = new byte[Color32ArrayToByteArray(pixels).Length]; Marshal.Copy(returnedPtr, returnedResult, 0, Color32ArrayToByteArray(pixels).Length); freeMem(returnedPtr); Debug.Log(returnedResult[0]); tex.SetPixels32(pixels); ri.texture = tex; tex.Apply(); // Sets texture of rawimage from canvas to be web camera view } public void AdjustBrightness(float b) { newBrightness = (int)b; } private static byte[] Color32ArrayToByteArray(Color32[] colors) { if (colors == null || colors.Length == 0) return null; int lengthOfColor32 = Marshal.SizeOf(typeof(Color32)); int length = lengthOfColor32 * colors.Length; byte[] bytes = new byte[length]; GCHandle handle = default(GCHandle); try { handle = GCHandle.Alloc(colors, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); Marshal.Copy(ptr, bytes, 0, length); } finally { if (handle != default(GCHandle)) handle.Free(); } return bytes; } } 

有很多方法可以从C#返回字节数组,下面是其中之一。 内存分配和解除分配都是用C ++完成的。 您必须调用该函数以从C#中释放内存。 我使示例非常简单,以便您可以轻松地将其集成到当前代码中。

IntPtr是这个答案的关键。

C ++

 char* getByteArray() { //Create your array(Allocate memory) char * arrayTest = new char[2]; //Do something to the Array arrayTest[0]=3; arrayTest[1]=5; //Return it return arrayTest; } int freeMem(char* arrayPtr){ delete[] arrayPtr; return 0; } 

C#

 [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr getByteArray(); [DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int freeMem(IntPtr ptr); //Test void Start() { //Call and return the pointer IntPtr returnedPtr = getIntArray(); //Create new Variable to Store the result byte[] returnedResult = new byte[2]; //Copy from result pointer to the C# variable Marshal.Copy(returnedPtr, returnedResult, 0, 2); //Free native memory freeMem(returnedPtr); //The returned value is saved in the returnedResult variable byte val1 = returnedResult[0]; byte val2 = returnedResult[1]; } 

您可以将额外的参数传递给函数,让我们说另一个字节数组,然后在adjustBrightnesss函数中用该数组替换myvector。 据我所知,你将获得具有修改值的数组