将字节数组从c 不受管理的dll传递到c#unity
Passing byte array from C++ unmanaged dll to C# unity
我试图将字节数组从未管理的C DLL返回到C#Unity。非常感谢您花时间帮助><我真的是Unity的DLL新手,所以我非常困惑两种语言如何一起工作。
cpp
问题在这里,我已经完成了我的计算,但是我正在努力寻找一种以数组格式返回C#的方法。
当前,字节阵列持有颜色代码,例如RGBA(223,124,23,255,212,12,143,234,255(,并重复
#include "WebcamDLL.h"
#include <vector>
extern "C" {
int adjustBrightnesss(unsigned char* bytes, int sizeOfArray)
{
std::vector<int> 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<AspectRatioFitter>(); // Gets the component AspectRatioFitter in script parent
ri = GetComponent<RawImage>(); // 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 <vector>
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<AspectRatioFitter>(); // Gets the component AspectRatioFitter in script parent
ri = GetComponent<RawImage>(); // 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];
}
您可以将一个额外的参数传递给该函数,假设另一个字节数组,然后在Adjustbrightness函数中用该数组替换MyVector。据我所知,您将获得带有修改值的数组
相关文章:
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- Unity在虚幻引擎4中的"Vector3.Slerp"等效C++?
- 我可以用C++/WinRT编写一个DLL,供windows桌面应用程序(而不是UWP)或Unity插件使用吗
- Unity 如何使用本机 dll 或转换为托管
- 在C 功能执行后,使用GCHANDLE CRALSES将大型结构从C#Unity脚本传递到C DLL
- 将字节数组从c 不受管理的dll传递到c#unity
- 从 Android 上的 Unity 中的 C++ DLL 访问 StreamingAssets 资源
- 在 Unity 中使用 x64 c++ dll 可以"Is not a valid Win32 application error"
- Unity内部编译器错误与自定义DLL
- Unity-如何使用C DLL
- 将结构(或类)从C DLL传递到C#(Unity 3D)
- 向c#封装的c++ dll发送值会导致Unity崩溃
- 在Unity中使用DLL, MonoBehaviour