marisademeglio
asked on
MFC DLL
Hi,
I need to create a dialog in an MFC DLL. It will be a plugin for my main application. Here are the basics of what I have set up:
1. client = MFC MDI app (running in Debug mode)
2. DLL = appwizard MFC extension DLL (running in debug mode)
Uses MFC libraries as a shared DLL
Has the following structure:
- CPluginDialog: CDialog-derived class
- something.cpp: wizard-generated DLL entry point
- IPlugin: exported interface for starting/stopping the plugin which looks like this:
class AFX_EXT_CLASS IPlugin
{
...
void Start()
{
CPluginDialog dlg;
dlg.DoModal();
}
};
I am getting a debug assertion upon dlg.DoModal. Also, adding the line AFX_MANAGE_STATE(AfxGetSta ticModuleS tate(...) doesn't help. I tried adding it in a few places. It gets linker errors.
Any ideas?
thanks!
marisa
I need to create a dialog in an MFC DLL. It will be a plugin for my main application. Here are the basics of what I have set up:
1. client = MFC MDI app (running in Debug mode)
2. DLL = appwizard MFC extension DLL (running in debug mode)
Uses MFC libraries as a shared DLL
Has the following structure:
- CPluginDialog: CDialog-derived class
- something.cpp: wizard-generated DLL entry point
- IPlugin: exported interface for starting/stopping the plugin which looks like this:
class AFX_EXT_CLASS IPlugin
{
...
void Start()
{
CPluginDialog dlg;
dlg.DoModal();
}
};
I am getting a debug assertion upon dlg.DoModal. Also, adding the line AFX_MANAGE_STATE(AfxGetSta
Any ideas?
thanks!
marisa
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Try putting a breakpoint on the line
dlg.DoModal();
Now step into the code. Where does it assert?
If you have an OnInitDialog in the CPluginDialog class then try a breakpoint there also.
dlg.DoModal();
Now step into the code. Where does it assert?
If you have an OnInitDialog in the CPluginDialog class then try a breakpoint there also.
ASKER
1. The linker errors are:
mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in pluginA.obj
mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in pluginA.obj
when I add AFX_MANAGE_STATE(AfxGetSta ticModuleS tate()); at the beginning of my Start() function.
2. I put a breakpoint in MyDialog::DoModal() and it crashes as it calls CDialog::DoModal.
The hWnd of MyDialog is NULL, which is probably what is causing the problem. But I don't know how to fix it...
Thanks
marisa
mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in pluginA.obj
mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in pluginA.obj
when I add AFX_MANAGE_STATE(AfxGetSta
2. I put a breakpoint in MyDialog::DoModal() and it crashes as it calls CDialog::DoModal.
The hWnd of MyDialog is NULL, which is probably what is causing the problem. But I don't know how to fix it...
Thanks
marisa
ASKER
Further info...
the assertion is happening here:
afxwin1.inl
line 22
the assertion is happening here:
afxwin1.inl
line 22
Did you read my post?
ASKER
Thanks Alex, I had missed it.
When I tried your suggestion, I get the same assertion as before, but at this line:
HINSTANCE h = AfxGetResourceHandle();
When I tried your suggestion, I get the same assertion as before, but at this line:
HINSTANCE h = AfxGetResourceHandle();
What assertion? Can you post assertion line (number and the whole function where assertion is raised)?
There are two types of MFC Dll. In one of them AFX_MANAGE_STATE is working. Another Dll type doesn't like AFX_MANAGE_STATE. I am always working with MFC extension Dll and use AfxGetResourceHandle/AfxSe tResourceH andle to manage Dll resources. Possibly your problem is the same.
ASKER
Assertion:
afxwin1.inl
line 22
And the function is:
void InterfaceForPluginA::Start ()
{
CPluginDialog dlg;
HINSTANCE h = AfxGetResourceHandle();
AfxSetResourceHandle(g_hDl l); // get hDll from HINSTANCE passed to DllMain
dlg.DoModal();
AfxSetResourceHandle(h);
}
afxwin1.inl
line 22
And the function is:
void InterfaceForPluginA::Start
{
CPluginDialog dlg;
HINSTANCE h = AfxGetResourceHandle();
AfxSetResourceHandle(g_hDl
dlg.DoModal();
AfxSetResourceHandle(h);
}
ASKER
Yeah, this is an extension DLL. It didn't like AFX_MANAGE_STATE.
Interesting. Current resource handler is NULL. Is this standard MFC Dll created by MFC Wizard statically linked to client MFC application? Or there is something custom in the way you use it? Try to continue ignoring assertion, what result do you have?
ASKER
This DLL is a standard MFC extension DLL, using MFC as a shared DLL.
It is statically linked to the client application (for now but in the end it will be loaded dynamically).
Assertion:
afxwin1.inl
line 19
In function:
int CPluginDialog::DoModal()
{
return CDialog::DoModal();
}
I ignore it twice then get an access violation before the calling function returns. I think it is trying to show the plugin window since I see a new window item on my taskbar menu named "plugin" (which would be the correct output of this test) right before it crashes.
It is statically linked to the client application (for now but in the end it will be loaded dynamically).
Assertion:
afxwin1.inl
line 19
In function:
int CPluginDialog::DoModal()
{
return CDialog::DoModal();
}
I ignore it twice then get an access violation before the calling function returns. I think it is trying to show the plugin window since I see a new window item on my taskbar menu named "plugin" (which would be the correct output of this test) right before it crashes.
ASKER
to clarify...
First I get this assertion:
Assertion: afxwin1.inl, line 22
In the IPlugin::Start() function.
Then I get (twice):
Assertion: afxwin1.inl, line 19
In CPluginDialog::DoModal()
Then it crashes with an access violation, I think as it tries to InitDialog().
First I get this assertion:
Assertion: afxwin1.inl, line 22
In the IPlugin::Start() function.
Then I get (twice):
Assertion: afxwin1.inl, line 19
In CPluginDialog::DoModal()
Then it crashes with an access violation, I think as it tries to InitDialog().
Something is completely wrong in your Dll or in the way it is invoked, if both AfxGetInstanceHandle and AfxGetResourceHandle fail.
Please post here file where DllMain function is placed.
Please post here file where DllMain function is placed.
ASKER
The file is almost 100% MFC wizard generated except for where I save the HINSTANCE of DLLMain.
Tomorrow I should be able to post the project files on our website and also include a sample test client app to reproduce the error.
Thanks for your help
marisa
--start file---
// pluginA.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include <afxdllx.h>
//added this line to wizard generated file
#include "global.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE PluginADLL = { NULL, NULL };
//global variable
HINSTANCE g_hDll;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpR eserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("PLUGINA.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(P luginADLL, hInstance))
return 0;
// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result.
//added this line to wizard generated file
g_hDll = hInstance;
new CDynLinkLibrary(PluginADLL );
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("PLUGINA.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(Plu ginADLL);
}
return 1; // ok
}
--end file--
Tomorrow I should be able to post the project files on our website and also include a sample test client app to reproduce the error.
Thanks for your help
marisa
--start file---
// pluginA.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include <afxdllx.h>
//added this line to wizard generated file
#include "global.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE PluginADLL = { NULL, NULL };
//global variable
HINSTANCE g_hDll;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpR
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("PLUGINA.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(P
return 0;
// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result.
//added this line to wizard generated file
g_hDll = hInstance;
new CDynLinkLibrary(PluginADLL
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("PLUGINA.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(Plu
}
return 1; // ok
}
--end file--
ASKER
Ok, I found it!
The DLL was compiled as MBCS and the client app as UNICODE. When I switched the DLL to MBCS, I had no problems.
The DLL code was written just as we talked about here, like in AlexFM's first post.
Thanks everyone!
marisa
The DLL was compiled as MBCS and the client app as UNICODE. When I switched the DLL to MBCS, I had no problems.
The DLL code was written just as we talked about here, like in AlexFM's first post.
Thanks everyone!
marisa
What linker errors? It should work ok.
void Start()
{
AFX_MANAGE_STATE(AfxGetSta
CPluginDialog dlg;
dlg.DoModal();
}