2010-01-29 45 views
3

我有一個庫,用於導出一個非託管C例程,該例程返回指向基於COM IUnknown對象的指針。 DLL未註冊,並且不是服務器。我想使用C#中的COM類型。從非託管代碼獲取COM對象

我已經爲COM類型編寫了C#接口。什麼是調用LoadLibrary()和GetProcAddress()的C#等價物?我如何調用GetProcAddress()的結果,然後調用它來加載COM接口指針?

這裏是C++的一個片段,說明我是什麼後:

// Assume I have previously declared IMyType 
HANDLE mylib = ::LoadLibrary("myfakecom.dll"); 
IUnknown* (*GetterFunc) getter; 
getter = (GetterFunc)::GetProcAddress(mylib, "GetFactory"); 
IUnknown *unk = getter(); 
IMyType *mytype = unk->QueryInterface(IID_MYTYPE); 

我的直覺說「用C++/CLI做吧」,但我不確定我會怎麼做這對於任何泛型類型,以及如何將原始IUnknown指針強制轉換爲我將在託管接口上使用[Guid]屬性聲明的管理器指針類型。

+0

你應該提出一個新問題,而不是試圖重複使用這個問題來跟進。新問題意味着新的眼睛。 – 2010-01-31 20:27:32

回答

1

你只需要使用互操作來描述你的GetFactory功能,這樣的事情

[DllImport("myfakecom.dll")] 
[return: MarshalAs(UnmanagedType.IUnknown)] 
static extern object GetFactory(); 

然後,一旦你在託管代碼的對象。強制轉換的QueryInterface

void Foo(Object unk) 
{ 
    IMyType mytype = (IMyType)unk; 
} 
相當於您將需要[的MarshalAs]屬性複製你的C++接口定義爲C#接口定義,有可能。但既然你已經這樣做了,其餘的應該很簡單。

我建議你從

IUnknown * GetFactory(); 

HRESULT GetFactory([out] IUnknown ** ppunk); 

似乎是由COM iterop代碼很強的假設,即所有的COM方法返回HRESULT改變你的工廠的原型,它會如果你在那裏跟蹤流量,可以更簡單地讓編組工作。

+0

太棒了!我沒有意識到COM interop的東西是用相同的P/Invoke編組類型實現的。應該很明顯。謝謝。 – Armentage 2010-01-31 19:16:29

+0

好的,這一切都適用於您將要調用的特定DLL的情況;但是,如果您想在運行時調用任何DLL,該怎麼辦? – Armentage 2010-01-31 20:08:47

+0

@ Armentage:我建議你提出一個新問題,我不知道答案是否定的,但我會在這裏打賭。 – 2010-01-31 20:12:24