我正在编写一个非托管dll (使用c++和WinAPI),但我想使用一些C#方法,因此,我使用C++/CLI创建了一个包装器。
但问题是:非托管dll将被‘注入’(LoadLibrary),而我被困在这里,不知道如何调用包装函数。
非托管代码:
#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吗?
我读过关于装载机锁的文章,但我不确定这是否是问题所在。
发布于 2015-12-21 21:39:00
从文档到DllMain
在DLL入口点可以安全执行的操作有很大的限制。有关调用DllMain不安全的特定Windows,请参见通用最佳实践。如果您只需要最简单的初始化,那么就在DLL的初始化函数中这样做。您可以要求应用程序在DllMain运行之后和调用DLL中的任何其他函数之前调用初始化函数。
调用托管代码是你不能做的事情之一!
处理这一问题的标准方法是在DllMain中创建一个线程,这是一个允许的操作,并从该线程调用托管代码。
发布于 2015-12-21 21:51:20
在C/C++标准中,Dlls和共享对象存在问题。
操作系统加载DLL,调用初始化全局变量的DllMain,然后加载依赖的DLL。
这意味着( a)在DllMain/全局构造过程中,加载程序锁( b)依赖的DLL可能不会被加载。
这意味着CLR可能不是活动的(而不是初始化的),如果需要加载程序锁定,则可能挂起。
推迟到以后才是最好的解决办法。
class ImportantOnceWork{
ImportantOnceWork()
{
MyEntryPoint();
}
};
int DoOnce()
{
static ImportantOnceWork val;
}然后在每个挂钩点调用DoOnce()。
https://stackoverflow.com/questions/34404665
复制相似问题