如何从本机代码编组输出字符串
How to marshal an out string from native code
具有按参数 returns 字符串(如 char *)的本机函数,在通过托管代码预分配 char * 并按参数传递它和分配 char 之间的最佳选择是什么* 从本机代码内部,然后从 c# 中释放它?
您能否向我解释一下为什么我应该使用一个而不是另一个?请仅在有特定原因更喜欢解决方案而不是其他解决方案时回答。如果这两种解决方案都可以,那么我的问题也可以被认为是有答案的。
作为奖励,我想知道在第一种情况下我应该如何从 c# 分配 char * 变量(使用 Marshal class 或使用简单的 new 或使用 StringBuilder 就像我经常看到的那样其他答案?)以及如果我在第二种情况下从本机代码内部创建 char * 变量,我应该如何删除指针。
从 C 函数 return a char*
并期望调用者将其 de-allocated 通常不是好的做法。调用者可能不会(正确或根本)不这样做,因此会泄漏内存。避免这种情况的一种常见方法(由 OpenGL、OpenCL 和我见过的其他库使用)是将原型声明为:
int GetString(char* str, int* len);
像这样的实现:
int GetString(char* str, int* len)
{
if (str == NULL)
{
len = internal_get_string_length();
return 0; // No errors
}
else
{
if (len <= internal_get_string_length())
return -1; // not enough space in str
char* internal_str = internal_get_string_ptr();
strcpy(str, internal_str);
return 0;
}
}
然后文档将声明如果 str
为 NULL,则要 returned 的字符串的长度将 returned in len
。否则,指针 str
应包含所需数量的字符。为了使用它,用户调用该函数两次,一次使用 NULL 表示 str
,一次使用 int 表示 len
,然后再次使用分配的 char 数组,只要 len
。 P/Invoking 这种函数的可能原型是:
// Declaration
[DllImport("myDll.dll")]
int GetString(StringBuilder sb, ref int len);
// Usage
int length;
GetString(null, length);
var sb = new StringBuilder(length); // Set capacity
GetString(sb, length);
Console.WriteLine(sb.ToString()); // Do stuff with C# string
希望对您有所帮助!
具有按参数 returns 字符串(如 char *)的本机函数,在通过托管代码预分配 char * 并按参数传递它和分配 char 之间的最佳选择是什么* 从本机代码内部,然后从 c# 中释放它?
您能否向我解释一下为什么我应该使用一个而不是另一个?请仅在有特定原因更喜欢解决方案而不是其他解决方案时回答。如果这两种解决方案都可以,那么我的问题也可以被认为是有答案的。
作为奖励,我想知道在第一种情况下我应该如何从 c# 分配 char * 变量(使用 Marshal class 或使用简单的 new 或使用 StringBuilder 就像我经常看到的那样其他答案?)以及如果我在第二种情况下从本机代码内部创建 char * 变量,我应该如何删除指针。
从 C 函数 return a char*
并期望调用者将其 de-allocated 通常不是好的做法。调用者可能不会(正确或根本)不这样做,因此会泄漏内存。避免这种情况的一种常见方法(由 OpenGL、OpenCL 和我见过的其他库使用)是将原型声明为:
int GetString(char* str, int* len);
像这样的实现:
int GetString(char* str, int* len)
{
if (str == NULL)
{
len = internal_get_string_length();
return 0; // No errors
}
else
{
if (len <= internal_get_string_length())
return -1; // not enough space in str
char* internal_str = internal_get_string_ptr();
strcpy(str, internal_str);
return 0;
}
}
然后文档将声明如果 str
为 NULL,则要 returned 的字符串的长度将 returned in len
。否则,指针 str
应包含所需数量的字符。为了使用它,用户调用该函数两次,一次使用 NULL 表示 str
,一次使用 int 表示 len
,然后再次使用分配的 char 数组,只要 len
。 P/Invoking 这种函数的可能原型是:
// Declaration
[DllImport("myDll.dll")]
int GetString(StringBuilder sb, ref int len);
// Usage
int length;
GetString(null, length);
var sb = new StringBuilder(length); // Set capacity
GetString(sb, length);
Console.WriteLine(sb.ToString()); // Do stuff with C# string
希望对您有所帮助!