Unity,C ++本机插件字节数组不匹配

Unity,C ++本机插件字节数组不匹配

问题描述:

在我的C ++本机插件中,我有一个电话

In my C++ native plugin I have a call

vector<unsigned char> getCPPOutput() {
    return some_vector;
}

在C#端,我接到了电话

In my C# side I have the call

[DllImport("MySharedObj")]
static extern byte[] getCPPOutput();

由于某些原因,尽管这两个调用之间不匹配,即如果在C ++中检查输出的数组大小:16777216(针对我的具体情况).

For some reason though I have a mismatch between these two calls, namely if in my C++ I check the size of the array I get as output: 16777216 (for my specific case).

当我检查字节数组的大小时,我得到:170409961

When I check the the size of the byte array I get: 170409961

在C#上的调用非常简单,就像这样:

The call on the C# is really simple, it is something like:

byte[] outputBuffer = getCPPOutput();

没有任何预分配.调用该函数之前我需要做些什么吗?

There's no preallocation whatsoever. Is there something I need to before calling the function?

我根本不是C#专家,可能是我缺少一些非常愚蠢的东西.

I'm not a C# expert at all, it might be I'm missing something very silly.

您的返回类型在C#中为byte[],在C ++中为vector<unsigned char>.这些不匹配.在其他问题中,鼓励您填充数组而不是返回数组,但是您仍然想返回数组,这是这样做的方法:

Your return type is byte[] in C# but vector<unsigned char> in C++. These don't match. In your other questions, you were encouraged to fill the array instead of returning it but you still want to return an array, this is how to do it:

Vector转换为数组,然后将其返回. C ++返回类型应为char*,而C#返回类型应为IntPtr.另外,您需要一种方法来告诉C#数组的大小.您可以使用参数来执行此操作.在C#端,您必须使用该参数返回的大小再次创建新数组.之后,使用Marshal.Copy将数据从IntPtr复制到该新阵列.

Convert the Vector to array then return it. The C++ return type should be char* and the C# return type should be IntPtr. Also, you need a way to tell C# the size of the array. You can do this with an argument. On the C# side, you have to create new array again with the size returned by that argument. After this, use Marshal.Copy to copy the data from IntPtr to that new array.

C ++:

char* getCPPOutput(int* outValue)
{
    //Convert the Vector to array
    char* vArrray = &some_vector[0];
    *outValue = some_vector.size();
    return vArrray;
}

C#:

[DllImport("MySharedObj", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getCPPOutput(out int outValue);


//Test
void Start() 
{
 int size = 0;

 //Call and return the pointer
 IntPtr returnedPtr = getCPPOutput(out size);

 //Create new Variable to Store the result
 byte[] returnedResult = new byte[size];

 //Copy from result pointer to the C# variable
 Marshal.Copy(returnedPtr, returnedResult, 0, size);


 //The returned value is saved in the returnedResult variable

}


关于您的C ++代码的注释:


Note about your C++ code:

我没有看到您的some_vector变量声明.如果在该函数中将其声明为局部变量,则它在堆栈上,您必须在new关键字下动态分配新数组,并创建另一个函数以在C#上接收到它后使用delete关键字释放它.边.除非将数组声明为static对象或使用new关键字动态分配,否则您不能在堆栈上返回数组.

I did not see your some_vector variable declaration. If this is declared in that function as a local variable then it's on the stack and you have to allocate new array dynamically with the new keyword and create a another function to free it with the delete keyword after receiving it on the C# side. You can't return array on the stack unless it is declared as a static object or dynamically allocated with the new keyword.