2010-11-12 71 views
8

我正在考虑使用字符#@!在我们的系统生成的一些COM接口中。 COM类型库也被导出到.NET。那些角色以后会给我带来麻烦吗?COM/.NET接口名称中的非字母数字字符

我已经测试了今天的大部分时间,这一切似乎都很好。我们的系统继续像往常一样继续工作。

我很谨慎的原因是这些字符在MIDL中是非法的,它使用C语法作为类型名称。但是我们不使用MIDL - 我们使用ICreateTypeInfo和ICreateTypeLib构建我们的类型库。看起来这只是一个MIDL限制,COM和.NET对非字母数字字符很满意。但也许有一些我不知道...

+4

好问题,因为它显示了彻底性。我喜欢这样的问题,因为这意味着至少有一些程序员会提前预测问题。 – 2010-11-12 08:33:22

回答

2

这就是我找到的。

我认为在COM中二进制级别的名称是合法的是没有问题的,因为COM接口的名称是它的IID,而文本名称只是文档。

在.NET方面,相关的规范是通用语言基础结构规范(ECMA-335,http://www.ecma-international.org/publications/standards/Ecma-335.htm)。我不知道.NET或单声道是否加在上面自己的限制 - 这样做会减少互操作性,但这是真实的世界。

8.5.1节介绍了通用类型系统中的有效类型名称,并简单地说使用代码点比较名称。奇怪的是,它没有提到名称的组成,只是名称如何比较。这一节由MSDN在http://msdn.microsoft.com/en-us/library/exy17tbw%28v=VS.85%29.aspx中解释,它表示只有两个限制是:(1)类型名称“被编码为Unicode(16位)字符的字符串”,以及(2)它们不能包含嵌入的0x0000。

我已经引用了大约16位的Unicode,而不是解释它,因为它使用不精确的语言。推测该页面的作者是UTF-16。在任何情况下,ECMA-335指定逐字节比较,并且不提及Unicode(关于类型名称),也不禁止嵌入的零。也许.NET在这里偏离了CTS,尽管我怀疑它。更有可能的是,这个MSDN页面的作者在编写它时正在考虑编程语言。

公共语言规范(也定义在ECMA-335中)定义了源代码中标识符的规则。标识符与我的问题没有直接关系,因为我的内部类型名称永远不会出现在源代码中,但是我一直在研究它。 CLS是CTS的一个子集,因此它的限制不一定是更广泛的CTS的一部分。 CLS第4条规定,标识符必须遵循Unicode标准3.0技术报告15附件7的规定 - 请参阅http://www.unicode.org/reports/tr15/tr15-18.html。该文件也有点模糊,因为它指的是“其他字母”和“连接器标点符号”,但没有定义它们。这有助于:http://notes.jschutz.net/topics/unicode/

ECMA规范的8.5.1节包含了一个非规范的注释,即CLS消费者(例如C#或Visual Studio类型的浏览器,我想)不需要使用违反CLS规则4的类型。“我的建议接口名称确实违反了本规则4.本文似乎暗示有效类型可能具有违反规则4的名称,并且CLS消费者应接受流氓名称或安全地忽略它。 (Visual Studio类型的浏览器毫无怨言地显示它。)

因此,我提出的类型名称在源代码中通常是非法的。但请注意,第10.1节(关于CLS中的标识符)指出:“由于其规则仅适用于导出到其他语言的项目,因此未从程序集中导出的私有成员或类型可以使用他们选择的任何名称。”

我得出结论:使用字符#@是安全的!在我的类型名称中,只要它们保留在二进制域中,并且永远不需要出现在源代码中,也不需要出现在程序集之外。事实上,他们从来没有在COM服务器之外使用过。

关于面向未来的一句话......虽然有一个名为“有效名称”的小节(8.5.1节),但CTS几乎没有关于类型名称组成的说法。他们可能会在未来改变这种状况,但是这个广泛而宽松的规范已经邀请我们所有人去做我们喜欢的事情。如果CTS的设计师想留下改变的空间,那么他们肯定会为此提供一些条款,或者至少不会那么慷慨。

+0

写得不错。你有一个错字,我认为你的意思是ECMA-335。我的研究遵循同一个主题。虽然我可以以不同的方式衡量正反两方面的情况,但你可以做一个好例子我反对的其余论点是Off Topic,相反,让我分享这个支持参考。 ECMA-335 Partition II有关元数据标识符的第5.3节语法说:“ILAsm语法允许使用任何可以使用Unicode字符集形成的标识符。为实现此目的,标识符应放在单引号内。它看起来不像MIDL,ILAsm允许和支持你不寻常的名字。 – jimhark 2010-11-30 18:14:55

+0

如果您遇到任何问题,请回到这里。谢谢。 – jimhark 2010-11-30 18:15:48

+0

谢谢,吉姆:-)我有兴趣听到你的反对意见......他们可能会涵盖我没有想到的事情。是的,如果有任何发展,我会回到这里。 (我也会修正这个错字。) – 2010-12-01 06:59:25

1

有趣的是,你似乎已经发现COM类型命名的漏洞。 Microsoft限制使用字符'#@!'作为MIDL中的标识符,但它们不会在ICreateTypeInfo和ICreateTypeLib接口中重复该限制。

今天使用这些字符有效,那么风险是什么?

  1. 好了,微软可能会认为这是一个错误 和 '修复' ICreateTypeInfo, ICreateTypeLib,净COM互操作 和/或.Net类型的命名在下一个版本 限制。

  2. 您正在创建并使用一个没有任何 有效MIDL定义的接口 。

  3. 您正在使用的名称将 可能必须更改如果(何时) 您从COM转换到.Net。 即使您只是想在.Net中创建一个 适配器类型,您也不会是 能够重用任何“无效” 名称。

  4. 这是否兼容Mono和 其他非Microsoft .Net兼容 技术?

  5. 有很多可以使用的(使用 像“_at_”,而不是 “@”等),以避免任何可能的 未来的问题已知有效 名字。

如果这些对您都不重要,那么您可能会很好。但是,我怀疑你提出这个问题,在某种程度上,它并不“感觉”你是对的。

祝你好运。

+0

下面是我的想法:在COM中,文本名称不是类型定义的一部分 - 它只是文档。所以在COM二进制级别没有问题。但我对.NET的底层细节不够熟悉,无法对.NET做出同样的判断。 (至少,还没有。) – 2010-11-24 05:21:46

+0

(哎呀,太快了。)这个产品在.NET中已经非常多了,所以.NET的角度是今天的一个实时问题。但是,接口名称永远不会出现在源代码中 - 这些接口只在内部使用,并由ITypeLib等加载(另一个人对该主题的评论神秘地从前一天消失...也许是因为我没有投票答复up或类似的东西)。 – 2010-11-24 05:26:00

+0

Microsoft不会改变ICreateTypeInfo等的行为在比赛的最后阶段。不太确定.NET,当然也不确定Mono。 – 2010-11-24 05:27:21

相关问题