簡體   English   中英

免注冊的類COM互操作和線程

[英]Registration-free COM-like interop and threading

我正在使用具有WPF GUI和非托管C ++后端的桌面應用程序。 我已經通過以下方式定義了API(C#版本,已截斷):

[Guid( "###" ), InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
interface iMyApp
{
    void aMethod();
}
[DllImport( "my.dll", PreserveSig = true )]
public extern static int create( string configPath, out iMyApp a );

在后端我有

__interface __declspec( uuid( "###" ) ) iMyApp: public IUnknown
{
    HRESULT __stdcall aMethod();
}

和經典的基於ATL的實現。

這很好並且快速,不需要COM注冊,類型庫,MIDL編譯器等。

問題是,我無法在C#中跨線程傳遞iMyApp實例,從而引發E_NOINTERFACE異常。

我的實現是線程中立的。

如何告訴.NET,以便它停止在線程間編組接口,而僅在所有線程上使用相同的IUnknown指針? 如果有問題,我只需要支持4.5+

正如Hans Passant所暗示的,此處的關鍵是CoCreateFreeThreadedMarshaler API。

添加一個私有變量CComPtr<IUnknown> m_ftm;

初始化該編組器:

HRESULT FinalConstruct()
{
    IUnknown* pUnk = GetUnknown();
    return CoCreateFreeThreadedMarshaler( pUnk, &m_ftm );
}

通過將以下行添加到接口映射,在QueryInterface中處理IID_IMarshal:

COM_INTERFACE_ENTRY_AGGREGATE( IID_IMarshal, m_ftm )

之后,C#代碼將愉快地從任何線程調用那些對象。 當然,您必須自己處理同步, CComAutoCriticalSection / CComCritSecLock通常可以提供幫助。

更新: MS在VS 2017中破壞了我的代碼,更新了答案。 請參閱VS2015版本的編輯歷史記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM