1

I have written an managed C++/CLI wrapper for mfc dll (C++) and have some access violations after second call of dll!

Wrapper

// in .h
typedef CKeyManagerServerApp* (*KeyManagerInstance)(CCommonUtils *);

ManagedKeyInterface::ManagedKeyInterface()
{
    HINSTANCE m_keyManagerLib = LoadLibrary("pathToDll");

    KeyManagerInstance _createInstance = (KeyManagerInstance)GetProcAddress(m_keyManagerLib, "GetInstance");

    // get native reader interface from managed reader interface
    CCommonUtils *nativeReaderInterface = static_cast<CCommonUtils*>(readerInterface->nativeReaderInterface.ToPointer());

    CKeyManagerServerApp *m_keyManagerApp = (_createInstance)(nativeReaderInterface );
}

ManagedKeyInterface::~ManagedKeyInterface()
{
    try
{
    DestroyKeyManagerInstance _destroyInstance = (DestroyKeyManagerInstance)GetProcAddress(m_keyManagerLib, "DestroyInstance");
    (_destroyInstance)(m_keyManagerApp);

    FreeLibrary(m_keyManagerLib);           
}
    catch(System::Exception ^e)
    {
        FreeLibrary(m_keyManagerLib);
    }
}

NATIVE MFC CLASS

extern "C" _declspec(dllexport) CKeyManagerServerApp* GetInstance(CCommonUtils *readerInterface)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    return new CKeyManagerServerApp(readerInterface);
}

extern "C" _declspec(dllexport) void DestroyInstance(CKeyManagerServerApp *ptr)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    delete ptr;
}

// constructor
CKeyManagerServerApp::CKeyManagerServerApp(CCommonUtils *readerInterface)   
{
    m_log = new Logging(loggingFilePath); // <--- ERROR at second call


    // reader interface object for communication 
    m_readerComm = new ReaderCommunication(readerInterface, m_log); 

    m_smartmaskcmds = new CSmartMaskCmds(m_readerComm, m_log);

    readerInterface = NULL;
}

// destructor
CKeyManagerServerApp::~CKeyManagerServerApp()
{
    // destruct objects     
    delete m_smartmaskcmds; 
    delete m_readerComm;    
    delete m_log;   
}

in ReaderCommunication and CSmartMaskCmds constr. the object will only assigned!

At first runtime of the C# program (loaded the wrapper with add reference) everything works fine, but when I start it again I get:

First-chance exception at 0x76f85b57 in TestKeyManagerApp.exe: 0xC0000005: Access violation reading location 0xdddddddd. First-chance exception at 0x75169617 in TestKeyManagerApp.exe: Microsoft C++ exception: CMemoryException at memory location 0x0024e820..

when I call m_log = new Logging(loggingFilePath)

It seems the destructor does not work right!?

Any ideas!!??

Thank you!

leon22
  • 5,280
  • 19
  • 62
  • 100
  • MFC has some pretty inscrutable rules about managing global state and DllMain(). Looks to me some initialization isn't happening the second time the DLL is getting loaded. Hard to see why you want to do it this way, just link to the import library of the DLL so you can directly call the method(s) and be done with it. – Hans Passant Jul 14 '11 at 13:53
  • Thanks! But the wrapper should not be every time new compiled when dll has changed! Hint: I also get a error message in the destr. of CKeyManagerServerApp in first run (destr. is not clean??? -> so some memory artefacts or assigments still exists) – leon22 Jul 14 '11 at 15:17
  • What is the call stack of the crash? – Martyn Lovell Jul 16 '11 at 17:08
  • Hi! I have found out that it is essential to derive my base MFC class from CWinApp and use AFX_MANAGE_STATE(AfxGetStaticModuleState()) for every exported method! I'm also using an pointer to another object as constr. param (when I understand it right this is not possible in regular mfc dll's -> but I also can't use extension dll's (loading the lib from C++/CLI wrapper)) What's the best solution for this? Links: http://msdn.microsoft.com/en-us/library/30c674tx(v=vs.80).aspx and http://msdn.microsoft.com/en-us/library/h5f7ck28(v=vs.80).aspx – leon22 Jul 25 '11 at 11:05

2 Answers2

2

When you see the value 0xdddddddd, it means that some pointer was deleted (VC will set that value on debug builds to help you recognize these cases). You don't tell us what's loggingFilePath and how Logging is implemented, but my guess is that loggingFilePath is deleted at some point, and Logging tries to access its value or a virtual function in the constructor (or initialization list).

This could also explain the crash in the destructor - you're deleting m_log, which probably holds an illegal pointer it got from loggingFilePath. When you try to use it again, you get the same crash.

Community
  • 1
  • 1
Eran
  • 21,632
  • 6
  • 56
  • 89
0

when I call m_log = new Logging(loggingFilePath)

What's happening behind the scenes? Find out where exactly it crashes. Enable unmanaged debugging if you are using C#. I guess the problem is under Logging constructor.

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • Hi! Unmanaged debugging is enabled! The application have an error in some of these destructor calls (delete m_smartmaskcmds; delete m_readerComm; delete m_log;) not always in m_log! So my guess is that the memory is not clean after calling the destruction of objects! But I will also post the logging class tomorrow! – leon22 Jul 17 '11 at 09:01