Question

I am working on an extension for a project that will allow hosting the CLR inside the core application. With this I plan to allow this extension to manage managed extensions that it loads/unloads inside itself. That being said, I need to use separate AppDomains to ensure unloading is possible.

Currently, I am able to get the domains setup and get the plugin file loaded but at that point I'm stuck. I'm not sure how to call functions inside the domains loaded assembly at will and so on.

Here is my loading setup so far, minus error checking and such:

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 );

I have a class library that all plugins must reference and use in order to be considered a plugin. Which so far is nothing more than a base class to inherit:

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

And then an extension would reference that class library and use that as its base:

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

What I am stuck at is how to do a few things:

  • How can I obtain the main class but as the base to invoke methods in the base that allow the main class to still handle?
  • How can I ensure that the main class inherits the base so I can ensure its a valid plugin file?
  • How I can freely invoke methods from the C++ side to fire events in the C# plugin.

For the firing events, the C++ plugin will call more things in the C# plugins once they are loaded, such as rendering events, command handling, etc.

Most of the examples I find online are specific to requiring the entire C# side to be static which I don't want. Also most do not use separate AppDomains and rather all execute in the default. I don't want this since it limits being able to unload a specific plugin.

If any other info is missing and needed feel free to let me know.

Was it helpful?

Solution

I resolved this issue by using a COM exposed interface for the C# side of things.

I have placed the FrameworkAPI inside a separate DLL and exposed it's main interface to COM then reference it in the plugins that will use it.

With it compiled with COM enabled, I can import the .tlb generated file to use the interface in C++ easily.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top