0

我正在尝试用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 下我尝试使用直接的方式来解决monostring来自 C的问题。

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

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

“没有办法控制运行时如何分配封送内存,或者它持续多长时间。这是至关重要的。如果运行时封送字符串(例如 UTF-16 到 Ansi 转换),则封送的字符串只会持续调用。非托管代码不能保留对此内存的引用,因为它将在调用结束后被释放。不注意此限制可能导致“奇怪的行为”,包括内存访问冲突和进程死亡“。

但该主题后来在同一个文档中用MarshallinginPtr和解决SafeHandles(没有现成的示例,而参考博客来自 2004/2005)。

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


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

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

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

4

1 回答 1

1

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

至于您的问题:您可以访问字符串字符并使用 mono_string_chars() 和 mono_string_length() 对它们执行您想要的操作。例如,您可以使用 Linux 和 OSX 上可用的 iconv(),或者您可以手动将 UTF16 转换为 UTF8 以获得最大控制。

于 2012-08-26T09:23:03.047 回答