2013-10-19 77 views
1

我試圖寫一個本地C++插件標準有管理的互操作庫。此本機C++庫使用C​​OM兼容接口設計。但是,它不會做任何類註冊的東西。與COM一樣,所有接口都來自IUnknown(無論如何都稱爲FUnknown,但同樣的3種方法)。COM互操作(-isch)接口編組結果簡單的通話

我已經寫加載我管理測試插件並檢索初始(根)接口(對象工廠模式 - 很像COM)一個簡單的C++控制檯應用程序通過一個導出的方法。我使用第三方DllExport代碼屬性實現 - 這似乎工作正常。 C++測試應用程序使用LoadLibrary/GetProcAddress併成功檢索對接口的引用。我可以在我的託管導出函數中設置一個斷點,並按預期擊中它。

然後,C++測試應用程序調用的AddRef上IUnknown接口(的一部分),並將其返回2 - 如可以預期。請注意,我的託管接口定義(計數器部分)不是從IUnknown派生的 - 或者包含這些方法。我會說這意味着管理式的封送魔術已經介入並提供了CCW。

然後C++測試應用程序在工廠接口上調用一個簡單的方法 - 一個只返回一個int32 - 並且也到達託管實現中(斷點被命中),但是當該方法返回時,它會拋出一個AccessViolationException - 某處在託管非託管過渡中。

class IPluginFactory : public FUnknown 
{ 
public: 
    // removed other methods before and after this one 

    virtual int32 PLUGIN_API countClasses() = 0;  
}; 

的INT32是#define和該PLUGIN_API被定義爲__stdcall - 這是據我可以告訴COM兼容。

我已經定義爲接口的管理表示如下:

[ComImport] 
[Guid("same guid as in C++ file")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IPluginFactory 
{ 
    [return: MarshalAs(UnmanagedType.I4)] 
    Int32 CountClasses(); 
} 

此方法的管理實現僅返回一個硬編碼號碼(1)。

我已經嘗試了很多東西(這麼多我甚至無法全部記住它們),並處於虧損如何解決這個問題,或者問題可能是什麼我目前。

任何幫助,非常感謝。感謝名單!

編輯:請求的詳細信息,FUnknown:

class FUnknown 
{ 
public: 
    virtual tresult PLUGIN_API queryInterface (const TUID iid, void** obj) = 0; 
    virtual uint32 PLUGIN_API addRef() = 0; 
    virtual uint32 PLUGIN_API release() = 0; 
}; 

回答

1

我們什麼也看不見FUnknown樣子。它必須必須與IUnknown相同以允許互操作。 CLR將自動調用AddRef,Release和QueryInterface。在FUnknown中確實有三種方法是非常重要的,如果FUnknown具有更多或更少,那麼當C#代碼調用CountClasses()時,最終會調用完全錯誤的方法。確實是觸發AVE的好方法。

一個問題,我們可以看到的是,CountClasses不兼容COM,方法必須返回一個Int32那就是HRESULT。一個錯誤代碼,一個不爲零的值會自動觸發C#程序中的異常。不兼容的方法簽名被支持,你必須使用一個屬性。像這樣:

[PreserveSig] 
int CountClasses(); 

這個錯誤否則不足以解釋AVE。接口不匹配是你可能的剋星。在這種情況下,你需要一個C++/CLI包裝器。

+0

我已經加入FUnknown細節原來的問題。我調用addRef成功(由包裝處理) - 所以我個人認爲這不是問題。我想我已經嘗試了PreserveSig - 但會再試一次。我希望我不需要CLI包裝.. :-( – obiwanjacobi

+0

嗯,看起來像PreserveSig修復它!非常感謝! – obiwanjacobi

+0

思考更多關於該簽名問題。這是否意味着我可以建模一個COM方法,看起來像這個HRESULT SomeMethod(ISomeInterface ** returnValue)像託管C#中的ISomeInterface SomeMethod()?這個包裝器會將其轉換嗎?我如何指示錯誤?拋出異常? – obiwanjacobi