2011-07-14 11 views
1

mfc dll(C++)用のマネージC++/CLIラッパーを作成しました。 ReaderCommunicationとCSmartMaskCmdsコンストラクタでC#プログラムから起動されたMFC dll(C++/CLIでラップされた)のアクセス違反

ラッパー

// 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; 
} 

。オブジェクトは割り当てられます! C#プログラムの最初の実行時に

(追加参照してラッパーをロードされた)すべてが正常に動作しますが、私は再びそれを起動したときに私が手:TestKeyManagerApp.exeで0x76f85b57で

初回例外:0xc0000005で:アクセス違反の読み取り場所は0xddddddddです。 TestKeyManagerApp.exeで0x75169617で 初回例外:マイクロソフトC++の例外:メモリ位置0x0024e820でCMemoryException ..

私はm_log =新しいログ(loggingFilePath)

呼び出すときにデストラクタが正しく動作しないようです! ?

ありがとうございました!

+0

MFCには、グローバル状態とDllMain()を管理するためのかなりわかりやすい規則があります。私には、DLLがロードされている2回目に初期化が行われていないように見えます。なぜこのようにしたいのか分かりません。DLLのインポートライブラリにリンクするだけで、メソッドを直接呼び出すことができます。 –

+0

ありがとう!しかし、dllが変更されたときに、コンパイルされるたびにラッパーが作成されるべきではありません!ヒント:destrにもエラーメッセージが表示されます。最初の実行時にCKeyManagerServerAppの(クリーナーではない-----いくつかのメモリアーチファクトまたはアシグメンテーションがまだ存在する) – leon22

+0

クラッシュのコールスタックとは何ですか? –

答えて

0

私は舞台裏で何が起こっているm_log =新しいログ(loggingFilePath)

呼び出しますか?正確にどこがクラッシュするかを調べる。 C#を使用している場合は、アンマネージデバッグを有効にします。私は問題がLoggingコンストラクタの下にあると思います。

+0

こんにちは!アンマネージデバッグが有効になっています!アプリケーションは、これらのデストラクタ呼び出しのいくつかにエラーがあります(delete m_smartmaskcmds; delete m_readerComm; delete m_log;)。必ずしもm_logにあるとは限りません!だから私の推測は、オブジェクトの破壊を呼び出した後にメモリがきれいではないということです!しかし、私は明日もロギングクラスを投稿します! – leon22

2

値が0xddddddddの場合は、some pointer was deleted(VCはデバッグビルドでその値を設定して、これらのケースを認識するのに役立ちます)を意味します。 loggingFilePathと、Loggingの実装方法は教えてくださいませんが、loggingFilePathがある時点で削除され、Loggingがコンストラクタ(または初期化リスト)の値にアクセスしようとしています。

これはデストラクタのクラッシュを説明することもできます - から得た不正なポインタを保持しているm_logを削除しています。もう一度使用しようとすると、同じクラッシュが発生します。

関連する問題