我正在探索从非托管C ++代码调用.net方法,并在How To Inject a Managed .NET Assembly (DLL) Into Another Process
中找到了下面的函数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();
}
在控制台应用程序中调用一次时,这没有问题。
我现在想将此函数拆分为在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
如何以及在何处声明ICLRRuntimeHost pClrHost / HRESULT hr以实现此目的?
答案 0 :(得分:1)
它们应该是全局(静态)变量,或者是某种单独的变量。每个进程只允许一个.NET运行时(至少这几天),所以尝试变得比这更聪明一点没什么意义。在DLL加载中填充全局变量,然后在DLL卸载期间将它们减少。
对于我做过的.NET / Mono嵌入项目,我创建了一个对象,其构造函数启动了运行时(即绑定/推送开始按钮),其析构函数将其关闭(停止/释放)。这样主应用程序可以选择如何操作,即将它放在main()中的堆栈上,或者在DLL加载期间执行new(),并在DLL卸载时删除。在这种情况下,您提到的指针将是您创建的新对象的实例变量,例如ClrEmbedManager。如果您的库不需要在具有不同行为的不同类型的应用程序中重用,那就太过分了。