2014-09-03 71 views
0

我具有限定一個枚舉和MIDL的接口等的ATL COM庫:揭露從嵌入的互操作類型的類型對其他組件

[uuid(65785D49-574A-4B1B-95F1-B9C7F283364A)] 
typedef enum Options 
{ 
    Option1, 
    Option2 
} Options; 

[ 
    object, 
    uuid(2E3D1B1A-DF95-434F-836B-73FF1245B608), 
    oleautomation, 
    nonextensible, 
    pointer_default(unique) 
] 
interface IExample : IUnknown 
{ 
    HRESULT Test([in] Options option, [out, retval] BSTR* str); 
}; 

我然後創建一個管理組件並引用TLB,它創建一個PIA並將這些類型(Embed Interop Types = true)嵌入到託管程序集中。

在託管程序集,我現在創建一個實現接口的類:

public class Example : IExample 
{ 
    public string Test(Options option) 
    { 
     return option.ToString(); 
    } 
} 

現在我想創建第三個組件引用的託管程序集並創建對象,然後調用了進去,但它不會讓我因爲選項是一個未引用類型(需要我包括從類型庫生成的PIA):

public class Equivalence 
{ 
    public void UseTest() 
    { 
     Example e = new Example(); 
     e.Test(Options.Option1); // recognizes that it requires an ExampleLib.Options parameter, but that type isn't available 
    } 
} 

使用反射器,我可以看到它的管理組件內,但它是不可見通過對象瀏覽器:

namespace ExampleLib 
{ 
    [ComImport, CompilerGenerated, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2E3D1B1A-DF95-434F-836B-73FF1245B608"), TypeIdentifier] 
    public interface IExample 

    [Guid("65785D49-574A-4B1B-95F1-B9C7F283364A"), CompilerGenerated, TypeIdentifier("15a6cf97-c415-4866-bdfb-7da65edb1faa", "ExampleLib.Options")] 
    public enum Options 
} 

我的管理組件本身就是用來被分配作爲API庫,我想揭露這個枚舉和接口,以便它可以通過外部各方,而無需交付PIA使用從類型庫生成的ATL COM庫。可能嗎?

+0

不要嵌入類型!因爲你想將ATL庫與你的API一起分發,所以它不是你想要的。只有在引用TLB的程序集中使用的類型才被嵌入,因此客戶端可能會錯過某些對象。相反,您應該從您的TLB創建一個PIA,將其部署到GAC中,並在每個要使用它的類型的程序集中引用它。 – Carsten 2014-09-04 10:36:00

+0

我們不需要(或者想要)外部客戶使用ATL庫,他們唯一的訪問權限應該是通過我們的託管API。因此,我們需要通過這個API公開的唯一類型是被嵌入的類型。我正在慢慢得出結論,我需要分發PIA才能工作,但我希望它可以嵌入到程序集中以減少依賴性。 – mford 2014-09-04 12:42:35

+0

您可以嵌入到程序集中的唯一東西是Interop類型,它與底層COM類型不同!無論如何,ATL庫*必須部署並註冊到客戶端,即使您正在嵌入互操作類型(這只是COM庫的包裝器)。由於這個客戶端能夠直接訪問你的非託管類型庫。控制這一點的唯一方法是通過生成和分配PIA。依賴性在這裏沒有爭議 - 它們是解決方案本質的結果。您不能通過刪除某些組件來減少它們。 – Carsten 2014-09-04 13:24:17

回答

0

顯然這是不能做到的。其中一個錯誤(CS1748)指出我this post其中說PIA必須通過兩個程序集鏈接。

相關問題