Solved

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

Posted on 2014-12-29
3
504 Views
Last Modified: 2014-12-29
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
0
Comment
Question by:festijazz
  • 2
3 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 40521882
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
 
LVL 1

Author Comment

by:festijazz
ID: 40521919
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
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 40521970
>> 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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

861 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question