正在从DLLMain调用托管代码

Calling managed code from DLLMain

本文关键字:调用 托管代码 DLLMain      更新时间:2023-10-16

我正在编写一个非托管dll(使用c++和WinAPI),但我想使用一些c#方法,所以我使用c++/CLI创建了一个包装器。

但问题是:非托管dll将被"注入"(LoadLibrary),我被困在这里,不知道如何调用Wrapper函数。

非托管代码:

#include <Windows.h>
//the function I want to call
__declspec(dllexport) void SimpleTest(int *p);
extern "C" __declspec(dllexport) void MyEntryPoint()
{
    int* test;
    SimpleTest(test);
}
BOOL WINAPI DllMain(/*DllMain parameters*/)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            MyEntryPoint();
            break;
    }
    return TRUE;
}

包装器(C++/CLI):

__declspec(dllexport) void SimpleTest(int* p)
{
    *p = 1;
}

我不知道这里发生了什么。没有加载.NET环境?包装器DLL没有加载?(我循环浏览了模块,但包装器不在那里)。

我必须手动初始化CLR吗?

我读过关于装载机锁定的文章,但我不确定这是否是这里的问题。

从文档到DllMain:

在DLL入口点中可以安全地执行的操作有很大的限制。有关在DllMain中调用不安全的特定Windows API,请参阅常规最佳实践。如果您需要除最简单的初始化之外的任何东西,请在DLL的初始化函数中执行。您可以要求应用程序在运行DllMain之后以及调用DLL中的任何其他函数之前调用初始化函数。

调用托管代码是不能做的事情之一!

处理此问题的标准方法是在DllMain中创建一个线程,这是一个允许的操作,并从该线程调用托管代码。

Dlls和共享对象在C/C++标准中存在问题。

操作系统加载DLL,调用DllMain初始化全局变量,然后加载相关DLL。

这意味着a) 在DllMain/global构造过程中,加载程序被锁定b) 可能无法加载依赖DLL。

这意味着CLR可能不是活动的(未初始化),如果需要加载程序锁定,则可能挂起。

推迟到以后才是最好的解决办法。

class ImportantOnceWork{
    ImportantOnceWork()
     {
         MyEntryPoint();
     }
};
int DoOnce()
{
    static ImportantOnceWork val;
}

然后调用DoOnce();在每个钩点。