title: Passing byte array from C++ unmanaged dll to C# unity
body: <p>I am trying to return the byte array from my unmanaged c++ dll back to c# unity.
  Thank you very much in advance for taking the time to help >&lt; I'm really new to DLL in unity so I'm extremely confused how 2 languages are even suppose to work together.</p>
  
  <p><strong>CPP</strong></p>
  
  <p>The problem is in here, I've done my calculations, but I'm struggling to find a way to return it back to c# with an array format.</p>
  
  <p>Currently, the byte array holds color codes e.g RGBA (223,124,23,255,212,143,234,255) and it repeats</p>
  
  <pre><code>#include "WebcamDLL.h"
  #include &lt;vector&gt;
  
  extern "C" {
  int adjustBrightnesss(unsigned char* bytes, int sizeOfArray)
  {
      std::vector&lt;int&gt; myvector;
      int alphaP = 0;
      for (int i = 0; i &lt; sizeOfArray; i++) {
          switch (alphaP) {
          case 0:
          case 1:
          case 2:
              myvector[i] = bytes[i] / 2;
              alphaP++;
              break;
          case 3:
              alphaP = 0;
              break;
          }
      }
      return bytes;
  }
  }
  </code></pre>
  
  <p><strong>Header file</strong></p>
  
  <pre><code>#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);
  }
  </code></pre>
  
  <p><strong>C# File</strong></p>
  
  <pre><code>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&lt;AspectRatioFitter&gt;(); // Gets the component AspectRatioFitter in script parent
          ri = GetComponent&lt;RawImage&gt;(); // 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;
      }
  }
  </code></pre>
  
  <p><strong>EDITTED CPP FILE</strong></p>
  
  <pre><code>#include "WebcamDLL.h"
  #include &lt;vector&gt;
  
  extern "C" {
      unsigned char* adjustBrightness(unsigned char* bytes, int sizeOfArray)
      {
          int alphaP = 0;
          for (int i = 0; i &lt; 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;
      }
  }
  </code></pre>
  
  <p><strong>EDITTED HEADER FILE</strong></p>
  
  <pre><code>#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);
  }
  </code></pre>
  
  <p><strong>EDITTED C# FILE</strong></p>
  
  <pre><code>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&lt;AspectRatioFitter&gt;(); // Gets the component AspectRatioFitter in script parent
          ri = GetComponent&lt;RawImage&gt;(); // 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;
      }
  }
  </code></pre>