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庫。可能嗎?
不要嵌入類型!因爲你想將ATL庫與你的API一起分發,所以它不是你想要的。只有在引用TLB的程序集中使用的類型才被嵌入,因此客戶端可能會錯過某些對象。相反,您應該從您的TLB創建一個PIA,將其部署到GAC中,並在每個要使用它的類型的程序集中引用它。 – Carsten 2014-09-04 10:36:00
我們不需要(或者想要)外部客戶使用ATL庫,他們唯一的訪問權限應該是通過我們的託管API。因此,我們需要通過這個API公開的唯一類型是被嵌入的類型。我正在慢慢得出結論,我需要分發PIA才能工作,但我希望它可以嵌入到程序集中以減少依賴性。 – mford 2014-09-04 12:42:35
您可以嵌入到程序集中的唯一東西是Interop類型,它與底層COM類型不同!無論如何,ATL庫*必須部署並註冊到客戶端,即使您正在嵌入互操作類型(這只是COM庫的包裝器)。由於這個客戶端能夠直接訪問你的非託管類型庫。控制這一點的唯一方法是通過生成和分配PIA。依賴性在這裏沒有爭議 - 它們是解決方案本質的結果。您不能通過刪除某些組件來減少它們。 – Carsten 2014-09-04 13:24:17