我正在尝试通过更有效的方式替换下面的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-step-4
“无法控制运行时如何分配封送内存,或者它持续多长时间。这是至关重要的。如果运行时封送 一个字符串(例如UTF-16到Ansi转换),编组的字符串将 只有通话才能持续。非托管代码无法保留 引用此内存,因为它将在通话结束后释放。 不注意这个限制可能导致“奇怪的行为”, 包括内存访问违规和进程死亡“。
但该主题后来在同一文档中使用Marshalling
,inPtr
和SafeHandles
进行了处理(没有现成的示例,而参考博客来自2004/2005)
是否有更新的文档或代码示例?
感谢您解决Lupus问题。对于像我这样不了解C#的人来说,这些调用是在名为object.h
的文件中定义的宏,因此如果您动态加载运行时,它们将被报告为未解析的符号。他们在这里:
#define mono_string_chars(s) ((gunichar2*)(s)->chars)
#define mono_string_length(s) ((s)->length)
似乎C#终于使用了指针。
答案 0 :(得分:1)
该文档是关于P / Invoke上的编组,这是一个与您正在展示的C代码无关的不同主题。
至于你的问题:你可以使用mono_string_chars()和mono_string_length()来访问字符串字符并使用它们执行所需的操作。例如,您可以使用在Linux和OSX上可用的iconv(),或者您可以手动将UTF16转换为UTF8以获得最大程度的控制。