1.No.
2。你必须自己做。
3.是
如果您在 C 或 C++ 端的函数内部分配内存,则必须释放它。我没有看到任何代码分配内存,但我假设你离开了那部分。此外,不要将堆栈上声明的变量返回给 C#。您最终会遇到未定义的行为,包括崩溃。
Here 是一个 C++ 解决方案。
对于 C 解决方案:
char* getByteArray()
{
//Create your array(Allocate memory)
char * arrayTest = malloc( 2 * sizeof(char) );
//Do something to the Array
arrayTest[0]=3;
arrayTest[1]=5;
//Return it
return arrayTest;
}
int freeMem(char* arrayPtr){
free(arrayPtr);
return 0;
}
唯一的区别是C版本使用malloc和free函数来分配和释放内存。
C#:
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getByteArray();
[DllImport("__Internal", 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];
}
请注意,这只是一个使用带有 2 个字符的 char 的测试。您可以通过将out int outValue 参数添加到C# 函数然后将int* outValue 参数添加到C 函数来使字符串的大小动态化。然后,您可以在 C 端将字符的大小写入此参数,并从 C# 端访问该大小。
然后可以将此大小传递给Marshal.Copy 函数的最后一个参数,并删除当前硬编码的2 值限制。我会把这个留给你做,但如果你感到困惑,请参阅this 帖子的例子。
更好的解决方案是将StringBuilder 传递给本机端,然后写入它。不好的一面是你必须按时声明StringBuilder 的大小。
C++:
void __cdecl _GetLookupStatus (char* data, size_t size)
{
strcpy_s(data, size, "Test");
}
C#:
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
public static extern int _GetLookupStatus(StringBuilder data, int size);
//Test
void Start()
{
StringBuilder buffer = new StringBuilder(500);
_GetLookupStatus (buffer, buffer.Capacity);
string result = buffer.ToString();
}
如果您正在寻找最快的方法,那么您应该在 C# 端使用 char 数组,将其固定在 C# 端,然后将其作为 IntPtr 发送到 C。 C端可以使用strcpy_s修改char数组。这样,就不会在 C 端分配内存。您只是在重新使用 C# 中的 char 数组的内存。您可以在答案here 的末尾看到float[] 示例。