2011-07-05 29 views
3

我正在做一個COM-interop項目。用C#和.NET Interop替換一些VB和C++ ATL COM項目。當我在.NET中定義枚舉並將它們設置爲ComVisible時,它們會以Typelib.EnumType_EnumValue的形式暴露給Typelib.EnumValue。 typelib導出器會這樣做,以確保值名稱是唯一的。但我知道我所有的枚舉都是獨一無二的,所以我不想下劃線。還有很多客戶代碼需要改變,如果我沒有擺脫下劃線。創建只包含枚舉的COM庫的問題

要找到這個問題的解決方案,我已經在一個IDL文件中定義了枚舉,並從中創建了一個typelib和.net interop。

[ 
    uuid(64893FD4-359D-46B9-BC1E-48C055796104), 
    version(1.0), 
    helpstring("ABC"), 
    helpfile("AAA.chm"), 
    helpcontext(0x00000001) 
] 

library EnumTypeLib 
{ 
    importlib("stdole2.tlb"); 
    typedef [uuid(8FF85069-C4E2-4540-A277-4C0F3C19B807), helpstring("MyEnum"), helpcontext(0x00000066)] 
    enum MyEnum { 
     Value1 = 0, 
     Value2 = 1, 
    } MyEnum; 
}; 

我用MIDL.exe創建了一個生成tlb文件的類型庫。

然後我用tlbimp.exe創建一個程序集。使用與其他Interop程序集相同的密鑰簽署程序集。

TLBIMP OpenStructureAdapterEnum.tlb /keyfile:KeyFile.snk

然後我註冊regasm.exe 裝配該組件看起來很好,並沒有包含下劃線枚舉。但問題是,無法從OLE/COM Object Viewer或VBA或VB6中看到COM庫。當我從另一個COM暴露的程序集引用枚舉時,包含對枚舉引用的接口部分將作爲resticted方法公開。

[restricted] void Missing7(); 
[restricted] void Missing8(); 
[restricted] void Missing9(); 
[restricted] void Missing10(); 

如何創建一個只包含枚舉(不帶下劃線)並引用其他.net互操作程序集的COM庫?

回答

0

要回答你最後一個問題。你想要的是TypeLib而不是COM庫。在COM接口是一堆代碼和函數指針的地方,TypeLib是與這些指針進行交互的地圖(以及定義和枚舉以及其他一些東西)。只有當他們走到一起時,纔有一個COM庫。由於沒有COM接口,因此不能有COM庫。

微軟提供了關於如何create a TypeLib without an interface的示例。這與你所描述的非常相似。你會注意到,它裏面沒有COM接口;正因爲如此,它必須保持低調的TypeLib。

下一個問題是.NET程序集。當您使用TlbImp.exe將枚舉導入到您的代碼中時,它允許您在代碼中使用這些枚舉 - 在您的程序集中。這是你可以用枚舉做什麼的限制。你不能導出這些枚舉,因爲它們不屬於你的.NET代碼。枚舉由TypeLib擁有。你的.NET代碼有權使用枚舉,但它不能聲明擁有枚舉。

最後,回答你的第一個問題。您需要使用.NET提供的功能。它能夠定義枚舉並導出它們並使它們可以從COM中看到。雖然我明白命​​名約定的挫敗感,但這不是你應該嘗試解決或繞過的問題。正如您所看到的,嘗試繞過命名約定這個小問題已經造成了重大問題,從而使您的新代碼無法使用。

1

我已經這樣做了:

In。NET,我創建了一個名爲PermissionControlLib一個COM可見的庫這樣一個枚舉:

public enum NetOperations 
{ 
    Oper1, 
    Oper2, 
    Oper3 
} 

在VB6中,我創建了另一個枚舉是這樣的:

Public Enum VBOperations 
    Oper1=NetOperations.NetOperations_Oper1, 
    Oper2=NetOperations.NetOperations_Oper2, 
    Oper3=NetOperations.NetOperations_Oper3 
End Enum 

用法:

Dim ud as PermissionControlLib.IUser 
Set ud = New User 
Dim b as Boolean 
b = ud.HasPermissionInOperation(VbOperations.Oper1)