Reputation: 163
I'm writing a unmanaged dll (with c++ and WinAPI) but I want to use some C# methods, so, I created a wrapper using C++/CLI.
But the problem is: The unmanaged dll will be 'injected' (LoadLibrary) and I'm stuck here with no clue of how I can call the Wrapper functions.
Unmanaged code:
#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;
}
The wrapper (C++/CLI):
__declspec(dllexport) void SimpleTest(int* p)
{
*p = 1;
}
I don't know what's happening here. The .NET environment wasn't loaded? The Wrapper DLL wasn't loaded? (I looped through the modules and the wrapper wasn't there).
Do I have to initialize the CLR manually?
I read about loader lock but I'm not sure if it is the problem here.
Upvotes: 1
Views: 2727
Reputation: 13073
Dlls and shared objects have a problematic life in the C/C++ standards.
The operating system loads a DLL, calls DllMain initialising global variables, then loads dependent DLLs.
This means that a) during DllMain/global construction you have the loader lock b) the depend DLLs might not be loaded.
This means that CLR may not be active (not initialized) and may hang if it requires loader lock.
Defering till later is the best solution.
class ImportantOnceWork{
ImportantOnceWork()
{
MyEntryPoint();
}
};
int DoOnce()
{
static ImportantOnceWork val;
}
Then call DoOnce(); at each hook point.
Upvotes: 0
Reputation: 612824
From the documentation to DllMain
:
There are significant limits on what you can safely do in a DLL entry point. See General Best Practices for specific Windows APIs that are unsafe to call in DllMain. If you need anything but the simplest initialization then do that in an initialization function for the DLL. You can require applications to call the initialization function after DllMain has run and before they call any other functions in the DLL.
Calling into managed code is one of those things that you cannot do!
The standard way to deal with this is to create a thread in the DllMain
, an action that is allowed, and call into the managed code from that thread.
Upvotes: 3