在 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 互操作中错误地指定编码)?或者也许应用程序内部有一些奇怪的代码?如果是封送问题,是否可以仅针对此属性修改它?

在 C# 中通过 COM 互操作(双 UTF8 编码?)封送字符串时,编码失败

事实证明,

Name是一个"内部"字符串,我应该对 GUI 中显示的文本使用属性UserName

即我改变了:

var property = ...;
property.Name = "中文";   // becomes "??"
property.Value = "中文"; // OK

对此:

var property = ...;
property.UserName = "中文";   // OK!
property.Value = "中文"; // OK

这奏效了。据推测,用户名是以某种方式从内部名称隐式设置的,忽略或错误处理编码。