2012-04-05 16 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並終止? – 2012-04-05 07:18:31

+0

因爲我需要密切關注應用程序,並且需要在運行時影響一些全局變量。 – Jeroen 2012-04-05 07:23:13

+0

我仍然發現,你可以重新初始化事物,而無需晦澀的黑客。我認爲「重置」更合適,「初始化」始終是提供_initial_值的過程。 – 2012-04-05 07:38:01

回答

1

如果本機DLL沒有提供重置其狀態的函數,那麼您將不得不卸載DLL並重新加載它。如果你使用隱式鏈接,那是不可能的。你必須使用顯式鏈接:LoadLibrary,GetProcAddress等。

我假設本地代碼包含在單獨的DLL中。如果情況並非如此,那麼你完全陷入困境。

+0

這不是我希望的答案,但無論如何要感謝。目前我有一個包含本機代碼的混合DLL。我會嘗試在第二個DLL中分離本機代碼。 – Jeroen 2012-04-05 07:19:17

+0

如果您擁有本機代碼,則可以實施重新初始化。但是你永遠不能重新初始化函數內部的靜態。重新加載擁有模塊是重置這些模塊的唯一方法。 – 2012-04-05 07:24:22

+0

我會嘗試重新加載,重新初始化所有變量將花費太多精力。而且,正如您所提到的,功能內部仍然存在靜態功能。 – Jeroen 2012-04-05 07:30:38

0

很簡單。

static char test; 
test = 0; 
+0

非常真實,但不是用於'do_stuff()'中的任何靜態變量的解決方案。實際上,你的解決方案類似於'char test = 0',也就是移除'static'。 – Jeroen 2012-04-05 06:59:01

+0

@Jeroen爲什麼不呢?使用init_stuff()在運行時初始化它們。事實上,這與去除靜電相似,您可能想問問自己爲什麼首先使用靜態。 – Lundin 2012-04-05 10:58:46