0
votes

I'm migrating an old OWL application to MFC. there were a main library that has the main dialogs and controls , I started writing an alternative classes of MFC to the old OWL like TDialog[inherits from CDialogEx], TEdit..... I added all the needed classes from the OWL now my library build successfully.

I created a new MFC Application [to test the library], i exported a function [SowDialogue] from the dll to be used in the Application , I added the .lib of dll to the MFC application, I called the function to show a simple dialog , the build go successfully, but at the first start the application fail with the following message

The assertion failed message

I clicked retry and the break to get the line that caused the assertion it was that one

The code where the assertion happened

So the problem is with the resources. when i link with the library the MFC can't get the right resources module.

I thought it was because i use a regular dll that uses MFC and shares MFC objects, if i must use an MFC extension library. how can i convert regular library to MFC extension library.

Or any solution to this disaster after a long work

EDIT


this is the call stack, there are no exported functions in this, its all in the application the error come before calling anything from the dll

The call stack when the assertion happened

Solution


the problem was solved when i converted the dll to an MFC extension library, really i created a new mfc extension dll and cheated it's properties, the dll main, the stafx includes and preprocessors definisions

static AFX_EXTENSION_MODULE MFCExtensionDLL = { NULL, NULL };

extern "C" int APIENTRY DllMain( HINSTANCE hInst, DWORD fdwReason, LPVOID)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("MFCExtension.DLL Initializing!\n");

        // Extension DLL one-time initialization
        if (!AfxInitExtensionModule(MFCExtensionDLL, hInst))
            return 0;


        new CDynLinkLibrary(MFCExtensionDLL);

        //My initialization code

        return 1;
    }
    else if (fdwReason == DLL_PROCESS_DETACH)
    {
        // Terminate the library before destructors are called
        AfxTermExtensionModule(MFCExtensionDLL);
        // my finalization code
        return 1;
    }
}

the properties

in the properties of project->configuration properties->general Use of MFC = Use MFC in a Shared DLL

,

in the properties of project->configuration properties->C/C++->Preprocessor->Preprocessor Definitions->add _AFXEXT , make sure to delete _USERDLL if it exists
2

2 Answers

1
votes

When using MFC in a .dll, you have to make sure that the .dll can find resource handles for things like strings and bitmaps in the .rc file. MFC maintains an internal state for each .dll that points to the resources for that .dll. When calling into that .dll from an application (or another .dll) you have to 'help' MFC get the internal state right or it will not be able to find your resource and will ASSERT.

I can't see the function immediately below the one in the call stack in your example, but if it is an exported function, the MFC state problem is likely what is going on.

Make sure you have put the AFX_MANAGE_STATE macro at the top of any functions accessible from outside (exported functions). That will go a long way to solving your problems.

Microsoft reference: http://msdn.microsoft.com/en-us/library/ba9d5yh5(v=vs.80).aspx

0
votes

If you use resources or windows from a dll file, you can try this way. This code can be in the dll itself. Whenever the resource is created the current resource handle of the main process will be set as the dll's resource handle and use the handle.

After any window creation or resource change revert it back to the old value.

hdllresource = ::LoadLibrary(<dllfile containing the resource>);
hcurrentInst = AfxGetResourceHandle();
AfxSetResourceHandle(hdllresource );

//do your window creation or resource loading stuff 

AfxSetResourceHandle(hdllresource);