2012-04-05 11 views
0

既存のアプリケーションをテストするために、私たちのシミュレーションアプリケーションにロードできるDLLを作成しました。私はdllの中から既存のアプリケーションをリセットするまで、すべてうまく動作しています。 main()は再起動されますが、メモリはリセット/初期化されていないようです。 目的は既存のアプリケーションでできるだけ変更しないことです。実際には、起動時に変数を初期化するためにアプリケーションを書き直したくありません。そのほかに、すべてのローカル静的変数も古い値を保持します。管理DLLのネイティブコードを再初期化する方法

以下は、DLL内から既存のアプリケーションを呼び出す方法のサンプルです。

void TimerThread::Run(void) 
{ 
    while(true) 
    { 
    if ((nullptr != mpMainThread) && (mpMainThread->ThreadState == System::Threading::ThreadState::Stopped)) 
    { 
     // Cleanup MainThread when thread has stopped 
     delete mpMainThread; 
     mpMainThread = nullptr; 
    } 

    if (nullptr == mpMainThread) 
    { 
     // (Re)create MainThread in which the existing application is executed 
     mpMainThread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(&Main)); 
     mpMainThread->Priority = System::Threading::ThreadPriority::Highest; 
     mpMainThread->Start(); 
    } 
    dtStartTime = System::DateTime::Now;   // Keep track when started. 
    if (nullptr != mpMainThread) 
    { 
     //Simulate timertick in existing application 
     main_callback_timer_elapsed(); 
    } 

    dtEndTime = System::DateTime::Now; 
    iDuration = dtEndTime->Millisecond - dtStartTime->Millisecond; // Determine execution time. 
    System::Threading::Thread::Sleep(((TIMER_INTERVAL - iDuration) > 0) ? (miInterval - iDuration) : 0); // Set sleep time depending on time spent 
    } 
} 

void TimerThread::Main(void) 
{ 
    main();  // Run main off existing application 
} 

void TimerThread::Reset(void) 
{ 
    mpMainThread->Abort();  // Reset existing application by aborting MainThread 
} 

既存のアプリケーションのメインはかなり一般的です。 main()の表示の下に。

int main(void) 
{ 
    static char test = 0; 

    init_stuff(); 

    while(true) 
    { 
    test = 1; 

    do_stuff(); 
    while(!timer_tick) 
    { 
     check_timer(); 
    } 
    timer_tick = FALSE; 
    } 
} 

静的テスト変数は、0で初期化され、無限ループで1に設定されます。アプリケーションがdllからリセットされると、メインが再起動しますが、テスト変数は値1を保持します。明らかに、アプリケーションをリセットすると、この変数を0にリセットします。

アイデア?

+0

あなたは単にProcess :: Start()でEXEを起動して終了しませんか? –

+0

私はアプリケーションを詳細に監視し、実行時にいくつかのグローバル変数に影響を与える必要があるためです。 – Jeroen

+0

私はまだそれが漠然としたハッキン​​グなしで事を再初期化できるという噂を見つける。私は "リセット"がより適切だと思う、 "初期化"は常に_initial_値を与えるプロセスです。 –

答えて

1

ネイティブDLLがその状態をリセットする機能を提供していない場合、あなたはDLLをアンロードし、それをリロードする必要があります。暗黙のリンクを使用している場合は不可能です。明示的なリンクを使用する必要があります:LoadLibrary、GetProcAddressなど

私はネイティブコードが別のDLLに含まれていると仮定しています。そうでない場合、あなたは完全に立ち往生しています。

+0

これは私が望んでいた答えではありませんが、とにかく感謝しています。現在、ネイティブコードを含む1つの混合DLLがあります。私は2番目のDLLでネイティブコードを分離しようとします。 – Jeroen

+0

ネイティブコードを所有している場合は、再初期化を実装できます。しかし、関数の中にある静的変数は決して再初期化できません。所有モジュールをリロードすることはそれらをリセットする唯一の方法です。 –

+0

私は再ロードを試みます、すべての変数を再初期化するにはあまりにも多くの努力が必要です。そして、あなたが言及したように、機能の内部にはまだ静的なものがあります。 – Jeroen

0

かなり簡単です。

static char test; 
test = 0; 
+0

非常に真ですが、 'do_stuff()'で使用される静的変数の解決策はありません。実際、あなたのソリューションは 'char test = 0;と似ています。つまり' static'を削除します。 – Jeroen

+0

@Jeroenなぜですか?実行時にinit_stuff()で初期化してください。確かにこれは静的の除去に似ています、なぜあなたは最初に静的を使用しているのか自問したいかもしれません。 – Lundin

関連する問題