从DLLMain调用托管代码

时间:2015-12-21 21:31:46

标签: c++ winapi interop clr dllmain

我正在编写一个非托管的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环境没有加载? Wrapper DLL没有加载? (我在模块中循环,包装器不在那里)。

我是否必须手动初始化CLR?

我读过有关装载机锁的信息,但我不确定这是否是问题。

2 个答案:

答案 0 :(得分:3)

从文档到DllMain

  

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

调用托管代码是您无法做到的事情之一!

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

答案 1 :(得分:0)

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

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

这意味着 a)在DllMain /全局构造期间,您有装载机锁 b)可能未加载depend DLL。

这意味着CLR可能未处于活动状态(未初始化),如果需要加载程序锁定,则可能会挂起。

推迟到以后是最好的解决方案。

 <div style="border: 1px solid blue;">
 <img id="myImage" src="../logo.JPG" /> </div>


 <div style="border: 1px solid red;">
 <img src="**SRC FROM IMAGE 1**" id="anotherImage" />
 </div> 
 <script type="text/javascript">
  function image() {
    var imgSource = document.getElementById('myImage').src;
    document.getElementById('anotherImage').src=imgSource;
  } 
  image();
</script>

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