2010-11-12 70 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

相關問題