在 C# 中通过 COM 互操作(双 UTF8 编码?)封送字符串时,编码失败
本文关键字:编码 字符串 失败 UTF8 COM 互操作 | 更新日期: 2023-09-27 18:36:12
我正在为Autodesk Navisworks编写一个插件,试图将C#Unicode字符串传递给COM对象上的属性。但是,字符串在进程的某个位置编码不正确。
var property = ...;
property.Name = "中文"; // becomes "??"
property.Value = "中文"; // OK
"中文"在用户界面中显示为"??",而仅限于ASCII的字符串工作得很好(例如"abcd")。此外,在同一对象上设置 Value-属性(VARIANT)工作得很好,但不能使用 Name。
进一步的探索使我尝试将字符串"ä"编码为utf-8:
C3 A4
并以某种方式将其"编码"为(Unicode)字符串:
property.Name = "'u00c3'u00a4"; // shows up as "ä"
令人惊讶的是,这似乎奏效了。
这促使我尝试以下方法:
var bytes = Encoding.UTF8.GetBytes("中文abcd");
char[] chars = new char[bytes.Length];
for(int i = 0; i < chars.Length; i++)
chars[i] = (char)bytes[i];
string s = new string(chars);
但是,当我使用它尝试编码"中文abcd"时,我只得到GUI中的第一个字符"中"。然而,使用"äabcd",我再次得到不止一个字符......
这是怎么回事?如何解决这个问题?是否是编组问题(例如,在 COM 互操作中错误地指定编码)?或者也许应用程序内部有一些奇怪的代码?如果是封送问题,是否可以仅针对此属性修改它?
事实证明,
Name
是一个"内部"字符串,我应该对 GUI 中显示的文本使用属性UserName
。
即我改变了:
var property = ...;
property.Name = "中文"; // becomes "??"
property.Value = "中文"; // OK
对此:
var property = ...;
property.UserName = "中文"; // OK!
property.Value = "中文"; // OK
这奏效了。据推测,用户名是以某种方式从内部名称隐式设置的,忽略或错误处理编码。