?
Solved

MFC DLL

Posted on 2005-03-17
17
Medium Priority
?
935 Views
Last Modified: 2013-11-20
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(AfxGetStaticModuleState(...) doesn't help.  I tried adding it in a few places.  It gets linker errors.

Any ideas?

thanks!
marisa
0
Comment
Question by:marisademeglio
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
17 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 13572364
HINSTANCE h = AfxGetResourceHandle();
AfxSetResourceHandle(hDll);   // get hDll from HINSTANCE passed to DllMain
dlg.DoModal();
AfxSetResourceHandle(h);

To get current Dll handle kep it in global variable and assign it's value in DllMain function.
0
 
LVL 16

Expert Comment

by:nonubik
ID: 13574014
>It gets linker errors.
What linker errors? It should work ok.

void Start()
{
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     CPluginDialog dlg;
     dlg.DoModal();
}
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 13574288
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:marisademeglio
ID: 13577074
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(AfxGetStaticModuleState()); 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
0
 

Author Comment

by:marisademeglio
ID: 13582378
Further info...

the assertion is happening here:
afxwin1.inl
line 22
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13585852
Did you read my post?
0
 

Author Comment

by:marisademeglio
ID: 13586016
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();
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13586073
What assertion? Can you post assertion line (number and the whole function where assertion is raised)?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13586116
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/AfxSetResourceHandle to manage Dll resources. Possibly your problem is the same.
0
 

Author Comment

by:marisademeglio
ID: 13586125
Assertion:
afxwin1.inl
line 22

And the function is:

void InterfaceForPluginA::Start()
{
      CPluginDialog dlg;

       HINSTANCE h = AfxGetResourceHandle();
      AfxSetResourceHandle(g_hDll);   // get hDll from HINSTANCE passed to DllMain
      dlg.DoModal();
      AfxSetResourceHandle(h);
}
0
 

Author Comment

by:marisademeglio
ID: 13586185
Yeah, this is an extension DLL.  It didn't like AFX_MANAGE_STATE.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13586209
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?
0
 

Author Comment

by:marisademeglio
ID: 13586388
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.


0
 

Author Comment

by:marisademeglio
ID: 13586446
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().
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13588971
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.
0
 

Author Comment

by:marisademeglio
ID: 13589374
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(lpReserved);

      if (dwReason == DLL_PROCESS_ATTACH)
      {
            TRACE0("PLUGINA.DLL Initializing!\n");
            
            // Extension DLL one-time initialization
            if (!AfxInitExtensionModule(PluginADLL, 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(PluginADLL);
      }
      return 1;   // ok
}

--end file--
0
 

Author Comment

by:marisademeglio
ID: 13596101
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
0

Featured Post

Get proactive database performance tuning online

At Percona’s web store you can order full Percona Database Performance Audit in minutes. Find out the health of your database, and how to improve it. Pay online with a credit card. Improve your database performance now!

Question has a verified solution.

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

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
In this article you will learn how to create a free basic website on Bitbucket, a git service provider. Polymer creates dynamic HTML components, which allow more flexibility than static HTML. This tutorial uses Ubuntu Linux but can also be done on W…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses

800 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