等效于mono_string_to_utf8(),无需分配和数据复制

本文关键字:分配 数据 复制 mono string utf8 to | 更新日期: 2025-01-25 11:12:42

我正试图用更高效的东西替换下面的C代码:

void mstr2str(MonoString *mstr)
{
   char *str = mono_string_to_utf8(mstr);
   printf("mono string: %s'n", str);
   g_free(str);
}

我的目标是避免mono_string_to_utf8()附带的内存分配和数据复制,因为C#返回给C的字符串可能非常大。

我已经阅读了关于使用Windows C++COM接口的建议,但在Linux下,我尝试使用一种直接的方法来从C.解决monostring问题

下面的参考表明这是"不可能":

http://www.mono-project.com/Interop_with_Native_Libraries#marshal-第4步

"无法控制运行时如何分配封送处理的内存,或它的持续时间。这一点至关重要。如果运行时封送处理字符串(例如UTF-16到Ansi的转换),封送处理的字符串将只持续通话的时间。非托管代码不能保留引用此内存,因为它将在调用结束后释放。不遵守这一限制可能会导致"奇怪的行为",包括内存访问违规和进程死亡"。

但是,稍后在同一文档中使用MarshallinginPtrSafeHandles来处理该主题(没有现成的示例,而参考博客是2004/2005年的)。

有更多最新的文档或代码示例吗?


感谢您的解决方案Lupus。对于那些像我一样不了解C#的人来说,这些调用是在一个名为object.h的文件中定义的宏,因此如果动态加载运行时,它们会被报告为未解析的符号。它们在这里:

#define mono_string_chars(s) ((gunichar2*)(s)->chars)
#define mono_string_length(s) ((s)->length)

似乎C#最后使用了指针。

等效于mono_string_to_utf8(),无需分配和数据复制

该文档是关于p/Invoke上的封送处理的,这是一个不同的主题,与您显示的C代码无关。

至于您的问题:您可以使用mono_string_chars()和mono_striing_length()来访问字符串并对其执行您想要的操作。例如,您可以使用Linux和OSX上提供的iconv(),也可以手动从UTF16转换为UTF8以获得最大控制。