欢迎光临
我们一直在努力

Marshalling 实战:C# 字符串到 C 指针的安全穿越指南

开场:

凌晨两点,游戏服务器的崩溃日志疯狂刷屏。你刚接入的某个 C 库通过 P/Invoke 传回了一串乱码,Profiler 指着托管堆里某个 string 的地址,而那个对象已经被 GC 悄悄搬走了。

这种跨语言调用的噩梦,几乎每个 Unity 开发者都遇到过。当你把 C# 字符串塞进 DllImport 的那一刻,CLR 就要把它翻译成 C 端能懂的 char*。这个翻译过程就是 Marshalling(封送)。它不是一行 [MarshalAs] 注解那么简单,而是数据格式、内存布局、GC 生命周期三方规则的精密博弈——任何一方理解不到位,换来的就是乱码、泄漏或玄学崩溃。

本文沿着一个字符串从托管堆到非托管内存的完整旅程,把每一步\”内部怎么走、为何这么设计\”讲透,最后给出 Unity 工程的落地清单。

一、两个世界的字符串:为什么必须\”翻译\”

要理解封送,先看双方的数据结构差异有多大:

  • C# string:托管堆上的对象,UTF-16 编码,带对象头与长度字段,不可变(immutable),地址随时可能被 GC 压缩堆时移动。
  • C char*:指向一段连续字节的裸指针,编码可能是 ANSI/UTF-8/UTF-16,以 \\0 结尾(长度不靠字段,靠扫描终止符),地址固定但生命周期全
赞(0)
未经允许不得转载:171主机测评 » Marshalling 实战:C# 字符串到 C 指针的安全穿越指南
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址