Class not instantiating in dll

I built the MFC project (executable file) as a dll or, more precisely, added export functions to it, like a DLL. I can load and execute exported functions, but the problem is that when loading the module the main class of the CMyApp theApp application CMyApp theApp not created. This means that I cannot use theApp object that I really want. I even modified the function below to fit the standard MFC DLL.

 BOOL CMyApp::InitInstance() { CWinApp::InitInstance(); return TRUE; } 

I am using LoadLibrary() to load exe / dll. Note that I am not exporting any C ++ class from dll, just a few standard C-style functions. These internal functions would like to use the main application object, but it was not created (its constructor is never called). What do I need for the application class to be created correctly, as it would in the standard mfc dll?

** Update **

Ideally, I would like to have exported functions available in exe, and I have already done it, but when I load it using LoadLibrary , theApp class theApp not receive an instance. I believe that this is the same behavior, even if it is a DLL. My projects have many dependencies and create a new dll project, and adding all the files and libraries is too cumbersome. I would really like to change the project settings for the current project, if any, so I can load it with the application class appropriately created, like a regular MFC dll. But the question is, what project parameters do I need to change?

Note. I will retrieve an instance of the main dialog object using #define . Basically, the dll version of the InitInstance() version can be as simple as I posted above.

+7
c ++ dll visual-studio-2010 mfc
source share
2 answers

What you describe is a Regular DLL dynamically linked to MFC . Selecting part of the description from this related article gives you a subset of the features:

A regular DLL dynamically linked to MFC has the following requirements:

  • These DLL files are compiled using _AFXDLL, as is the executable file that is dynamically linked to the MFC DLL. But _USRDLL is also defined as a regular DLL statically linked to MFC.

  • This type of DLL should create an instance of the CWinApp class.

  • This type of DLL uses the DllMain provided by MFC. Put all the DLL initialization code in the member function of the InitInstance and the termination code in ExitInstance, as in a regular MFC application.

If you use the new Wizatd project from VS2010 and choose the option to create an MFC DLL, you get this by default, although you can choose other types of DLLs from the wizard options:

wizard

So, create a regular DLL. It will generate the necessary template code for you, including the CWinApp class. For example:

 // CMFCLibrary1App BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp) END_MESSAGE_MAP() // CMFCLibrary1App construction CMFCLibrary1App::CMFCLibrary1App() { // TODO: add construction code here, // Place all significant initialization in InitInstance } // The one and only CMFCLibrary1App object CMFCLibrary1App theApp; // CMFCLibrary1App initialization BOOL CMFCLibrary1App::InitInstance() { CWinApp::InitInstance(); return TRUE; } 

I suggest you create such a project, and then put the existing code into it, after which you will have all the correct settings and structure of the project from the very beginning. This is much easier than trying to convert, for example. exe project for dll project.

Be sure to note the differences in how you should write exported functions. As stated above,

Since this type of DLL uses the dynamic link version of the MFC library, you must explicitly set the current state of the module to the DLL. To do this, use the AFX_MANAGE_STATE macro at the beginning, each function is exported from a DLL.

Thus, even if you export only C-style functions, if they wrap objects that use MFC, then exported functions and any public functions of exported classes should use the above method, especially for multi-threaded applications.

Comments are also inserted into the New Project template to explain this too:

 //TODO: If this DLL is dynamically linked against the MFC DLLs, // any functions exported from this DLL which call into // MFC must have the AFX_MANAGE_STATE macro added at the // very beginning of the function. // // For example: // // extern "C" BOOL PASCAL EXPORT ExportedFunction() // { // AFX_MANAGE_STATE(AfxGetStaticModuleState()); // // normal function body here // } // // It is very important that this macro appear in each // function, prior to any calls into MFC. This means that // it must appear as the first statement within the // function, even before any object variable declarations // as their constructors may generate calls into the MFC // DLL. // // Please see MFC Technical Notes 33 and 58 for additional // details. // 

The technical notes mentioned in the comments above are as follows:

Seeing that you are using LoadLibrary to dynamically load your DLL, if you are doing this from an MFC application, you would be wise to use AfxLoadLibrary instead (and the corresponding AfxFreeLibrary ). As MSDN says:

For MFC applications loading DLL files, we recommend that you use AfxLoadLibrary instead of LoadLibrary . The AfxLoadLibrary handles thread synchronization before you call LoadLibrary . The interface (function prototype) before AfxLoadLibrary is the same as LoadLibrary .

The documentation for AfxLoadLibrary contains more detailed information.

+6
source share

I had the same problem and my problem was empty lpszClassName for RegisterClassEx . Make sure you call CreateWindow , then with the same line.

If this is not the case for your problem, print the actual error message using GetLastError() . The absence of lpszClassName given to me in error code 1407 .

0
source share

All Articles