在C ++中托管CLR Runtime

时间:2012-11-22 18:37:44

标签: c# plugins clr clr-hosting

我正在开发一个项目的扩展,允许在核心应用程序中托管CLR。有了这个,我计划允许这个扩展来管理它自己加载/卸载的托管扩展。话虽这么说,我需要使用单独的AppDomains来确保卸载是可能的。

目前,我能够设置域并加载插件文件,但此时我已经卡住了。我不知道如何随意调用域加载程序集中的函数等等。

这是我到目前为止的加载设置,减去错误检查等等:

ICorRuntimeHost* lpRuntimeHost = NULL;
CorBindToRuntimeEx( L"v4.0.30319", L"wks", 0, CLSID_CorRuntimeHost, IID_PPV_ARGS( &lpRuntimeHost ) );

lpRuntimeHost->Start();

// File data read from disk. 
// Dll file just CreateFile/ReadFile and insert into pluginFileData.
CComSafeArray<BYTE> pluginFileData;

IUnknown* lpUnknown = NULL;
lpRuntimeHost->CreateDomain( wstrPlugin.c_str(), NULL, &lpUnknown );

CComPtr<_AppDomain> appDomain = NULL;
lpUnknown->QueryInterface( &appDomain.p );

CComPtr<_Assembly> appAssembly = NULL;
hResult = appDomain->Load_3( pluginFileData, &appAssembly );

我有一个类库,所有插件必须引用和使用才能被视为插件。到目前为止,这只是一个继承的基类:

namespace FrameworkAPI
{
    public class IFrameworkPlugin
    {
        public override bool Initialize(IntPtr interfaceObj)
        {
            return false;
        }
    }
}

然后扩展会引用该类库并将其作为基础:

namespace ClassLibrary1
{
    public class Main : IFrameworkPlugin
    {
        public override bool Initialize(IntPtr interfaceObj)
        {
            // Return true to stay loaded.
            return true;
        }
    }
}

我所坚持的是如何做一些事情:

  • 如何获取主类,但作为调用基类中允许主类仍处理的方法的基础?
  • 如何确保主类继承基类以便确保其有效的插件文件?
  • 如何从C ++端自由调用方法来触发C#插件中的事件。

对于触发事件,C ++插件在加载后会调用C#插件中的更多内容,例如渲染事件,命令处理等。

我在网上找到的大多数例子都是特定的,要求整个C#端是静态的,我不想要。此外,大多数不使用单独的AppDomain,而是全部在默认情况下执行。我不想要这个,因为它限制了能够卸载特定的插件。

如果缺少任何其他信息,请随时告诉我。

1 个答案:

答案 0 :(得分:0)

我通过为C#端使用COM公开接口解决了这个问题。

我已将FrameworkAPI放在一个单独的DLL中,并将其主界面暴露给COM,然后在将使用它的插件中引用它。

在启用COM的情况下编译它,我可以导入.tlb生成的文件,以便轻松地在C ++中使用该接口。