如何在通过C ++ DLL调用时拆分Dot Net Hosting功能

时间:2022-09-01 17:53:31

I am exploring calling .net methods from unmanaged C++ code and have found the function below in How To Inject a Managed .NET Assembly (DLL) Into Another Process

我正在探索从非托管C ++代码调用.net方法,并在如何将托管.NET程序集(DLL)注入另一个进程中找到了以下函数

void StartTheDotNetRuntime()
{
    // Bind to the CLR runtime..
    ICLRRuntimeHost *pClrHost = NULL;
    HRESULT hr = CorBindToRuntimeEx(
        NULL, L"wks", 0, CLSID_CLRRuntimeHost,
        IID_ICLRRuntimeHost, (PVOID*)&pClrHost);

    // Push the CLR start button
    hr = pClrHost->Start();

    // Okay, the CLR is up and running in this (previously native) process.
    // Now call a method on our managed class library.
    DWORD dwRet = 0;
    hr = pClrHost->ExecuteInDefaultAppDomain(
        L"c:\\PathToYourManagedAssembly\\MyManagedAssembly.dll",
        L"MyNamespace.MyClass", L"MyMethod", L"MyParameter", &dwRet);

    // Stop the CLR runtime
    hr = pClrHost->Stop();

    // Don't forget to clean up.
    pClrHost->Release();
}

This works with no problem when called once in a console application.

在控制台应用程序中调用一次时,这没有问题。

I now want to split this function for use within a dll, logically this should be in three parts

我现在想要拆分这个函数以便在dll中使用,逻辑上这应该分为三个部分

Method - DLLMain
    DLL_PROCESS_ATTACH
         Bind to the CLR runtime
         Push the CLR start button

    DLL_PROCESS_DETACH
         Stop the CLR runtime
         Do not forget to clean up.

Method - CallDotNetToDoSomething

How and where do I declare the ICLRRuntimeHost pClrHost/HRESULT hr in order to achieve this?

如何以及在何处声明ICLRRuntimeHost pClrHost / HRESULT hr以实现此目的?

1 个解决方案

#1


They should likely be global (static) variables, or in a singleton of some sort. There is only one .NET runtime allowed per process (at least these days), so there is little sense in trying to be a whole lot more clever than that. Populate the globals in DLL load, then depopulate them during DLL unload.

它们应该是全局(静态)变量,或者是某种单独的变量。每个进程只允许一个.NET运行时(至少这几天),所以试图变得比这更聪明一点没什么意义。填充DLL加载中的全局变量,然后在DLL卸载期间将它们减少。

For a .NET/Mono embedding project I did, I created an object whose constructor booted up the runtime (i.e. bind/push start button) and whose destructor shut it down (stop/release). This way the main application could choose how to operate, i.e. put it on the stack in main(), or do a new() during DLL load, and delete in DLL unload. In that case, the pointers you mention would be instance variables of a new object you create, e.g. ClrEmbedManager. That's overkill if your library doesn't need to be reused in different kinds of applications with different behaviors.

对于我做的.NET / Mono嵌入项目,我创建了一个对象,其构造函数启动了运行时(即绑定/推送开始按钮),其析构函数将其关闭(停止/释放)。这样主应用程序可以选择如何操作,即将它放在main()的堆栈中,或者在DLL加载期间执行new(),并在DLL卸载时删除。在这种情况下,您提到的指针将是您创建的新对象的实例变量,例如ClrEmbedManager。如果您的库不需要在具有不同行为的不同类型的应用程序中重用,那就太过分了。

#1


They should likely be global (static) variables, or in a singleton of some sort. There is only one .NET runtime allowed per process (at least these days), so there is little sense in trying to be a whole lot more clever than that. Populate the globals in DLL load, then depopulate them during DLL unload.

它们应该是全局(静态)变量,或者是某种单独的变量。每个进程只允许一个.NET运行时(至少这几天),所以试图变得比这更聪明一点没什么意义。填充DLL加载中的全局变量,然后在DLL卸载期间将它们减少。

For a .NET/Mono embedding project I did, I created an object whose constructor booted up the runtime (i.e. bind/push start button) and whose destructor shut it down (stop/release). This way the main application could choose how to operate, i.e. put it on the stack in main(), or do a new() during DLL load, and delete in DLL unload. In that case, the pointers you mention would be instance variables of a new object you create, e.g. ClrEmbedManager. That's overkill if your library doesn't need to be reused in different kinds of applications with different behaviors.

对于我做的.NET / Mono嵌入项目,我创建了一个对象,其构造函数启动了运行时(即绑定/推送开始按钮),其析构函数将其关闭(停止/释放)。这样主应用程序可以选择如何操作,即将它放在main()的堆栈中,或者在DLL加载期间执行new(),并在DLL卸载时删除。在这种情况下,您提到的指针将是您创建的新对象的实例变量,例如ClrEmbedManager。如果您的库不需要在具有不同行为的不同类型的应用程序中重用,那就太过分了。