Issue: Attempt to use MSIL code from this assembly during native code initialization

Hello Everyone,
 
I have the following issue I would like to share with you:
 
I added to a dynamic library with MFC feature, the /clr option.
 
Since I have added this option, the library seems to behave properly expect that I cannot set code into DllMain statment as I was doing before the modification.
 
Let's add a MessageBox after CoInitialize:
#pragma unmanaged
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	g_hThisDll = hInstance;
 
    switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
			CoInitialize(NULL);
 
			::MessageBox(NULL, "DllMain", "mpOLEAutomationCLR", MB_OK);
			break;
 
		case DLL_THREAD_ATTACH:
			break;
		case DLL_THREAD_DETACH:
			delete g_pcfOleAutomationCLR;
			CoUninitialize();
			break;
		case DLL_PROCESS_DETACH:
			break;
    }	
	return TRUE;
 
}

Open in new window


Now, if I run:
C:\Windows\SysWOW64\regsvr32.exe ".\Debug\mpOLEAutomationCLR.dll"
 
It prompts the following error dialog box:

IssueError.jpg
If I remove the MessageBox line:
 
#pragma unmanaged
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    g_hThisDll = hInstance;
 
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            CoInitialize(NULL);
 
            //::MessageBox(NULL, "DllMain", "mpOLEAutomationCLR", MB_OK);
            break;
 
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            delete g_pcfOleAutomationCLR;
            CoUninitialize();
            break;
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
 
}

Open in new window


The regsv32.exe command line will return the expected messagebox.
 
IssueOK.jpg
I have added the sample program project to show you or try the issue.
Sample program link
 
Does somebody have a explanation or a fix to allow me to add code into the DllMain entry point.
 
Thank you very much in advance.
Happy end year season.
Best regards.
FestiJazz
LVL 1
festijazzAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
MSDN is pretty clear about that issue: http://msdn.microsoft.com/en-us/library/ms173266.aspx ("Initialization of Mixed Assemblies")

Code within DllMain must not access the CLR. This means that DllMain should make no calls to managed functions, directly or indirectly; no managed code should be declared or implemented in DllMain; and no garbage collection or automatic library loading should take place within DllMain.

I only can assume that calling an UI function like 'MessageBox()' causes some CLR initialization code to be executed, which in turn triggers the error. But, why do you need that 'MessageBox()' call in the 1st place? 'DllMain()' (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx) should only contain the most necessary code anyway, or as MS puts it:

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.
0
festijazzAuthor Commented:
Hello jkr,

Thank you for your reply.

Let me comment a bit more about my query.

Before I migrated the code from vs6 to vs2010, I added into DllMain, the HeapCompatibilityInformation method to support: low-fragmentation heap.
	switch ( Reason ) 
	{

		case DLL_PROCESS_ATTACH:
			if (TRUE)
			{
				for (i = 0; i < nheaps; i++) 
				{
					HeapSetInformation(heaps[i],
						HeapCompatibilityInformation,
						&HeapFragValue,
						sizeof(HeapFragValue));
                               }
			}
                        break;
        }

Open in new window



As I am not sure if this is correctly executed.  I added a messagebox to validate the execution but with the CLR option this does not work and it reports the message mentioned in the issue description.

How could I then allow this ?
Do I need  to move it from the DllMain to a DllInit method ?

Thank you very much in advance.
Best regards,
Michel
0
jkrCommented:
>> Do I need  to move it from the DllMain to a DllInit method ?

That is exactly what MS recommends, and I concur. BTW, if you need diagnostic output, 'MessageBox()' is overkill. I'd rather suggest using 'OutputDebugString()' (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx) and a viewer like 'DebugView' (http://technet.microsoft.com/en-us/sysinternals/bb896647)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.