COM / .NET接口名称中的非字母数字字符

时间:2010-11-12 05:30:34

标签: .net com typename typelib

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

我今天大部分时间都测试了它,一切看起来都很好。我们的系统继续像往常一样工作。

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

2 个答案:

答案 0 :(得分:2)

这是我发现的。

我认为毫无疑问,COM中的二进制级别的名称是合法的,因为COM接口的名称是其IID,文本名称只是文档。

在.NET方面,相关规范是公共语言基础结构规范(ECMA-335,http://www.ecma-international.org/publications/standards/Ecma-335.htm。)我想知道.NET或Mono是否在顶部添加自己的限制 - 这样做会降低互操作性,但这是现实世界。

第8.5.1节介绍了Common Type System中的有效类型名称,并简单地说使用代码点比较名称。奇怪的是,它没有说明名称的构成,只是如何比较名称。本节由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设计师想要为变革留出空间,那么他们肯定会为此制定一些条款,或者至少不那么慷慨。

答案 1 :(得分:1)

有趣的是,您似乎在COM类型命名中找到了漏洞。微软限制使用字符'#@!'作为MIDL中的标识符,但它们不会在ICreateTypeInfo和ICreateTypeLib接口中复制该限制。

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

  1. 好吧,微软可以将其视为一个 bug和'fix'ICreateTypeInfo, ICreateTypeLib,.Net COM Interop和/或.Net类型命名 下一版本中的限制。

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

  3. 你正在使用的名字 可能必须改变if(when) 你从COM过渡到.Net。 即使你想创造一个 .Net中的适配器类型你不会 能够重用任何“无效” 名。

  4. 这与Mono兼容吗? 其他非Microsoft .Net兼容 技术

  5. 有很多已知有效的 可以使用的名称(使用 比如“_at_”而不是“@” '{{1}}'等)以避免任何可能的 未来的问题。

  6. 如果这对你来说都不重要,那么你可能会没事的。但我怀疑你提出这个问题的事实,在某种程度上它并不适合你。

    祝你好运。