2011-06-14 47 views
4

原來的問題如何手動運行位於C消息泵++

我們的應用程序使用CSocket類要求的消息泵是爲了運行爲它工作。目前,切換到另一個套接字實現是不切實際的,儘管這是我們最終想要達成的目標。

該應用程序是在Visual C++(NOT管理)。

我們目前通過使用C#.NET服務啓動器啓動C++ DLL,該啓動器使用Application.Run啓動線程以獲取消息泵,然後使用DllImport在我們的DLL中啓動啓動方法。

有許多問題與此相關,最緊迫的就是一個如果DLL崩潰因任何原因,我們沒有得到一個轉儲文件!

由於這一結果,我們切換到C++服務啓動,雖然我們很好用它的服務方面我們是如何得到的消息泵會有點難倒。

我看了一下谷歌和這裏的一些問題,但我的問題的一部分是缺乏基本的C++知識,所以如果這是一個愚蠢的問題,如果有人可以指出我正確的方向,將非常讚賞道歉。

提前感謝 馬特Peddlesden

更多信息

,我們試圖取代目前的C#的服務確實基本上是這樣的:

public void PumpThread() 
{ 
    DLLStart(); 
    Application.Run(); 
} 

protected override void OnStart(string[] args) 
{ 
    try 
    { 
     Thread pumpThread = new Thread(new ThreadStart(PumpThread)); 
     pumpThread.IsBackground = true; 
     pumpThread.Start(); 
    } 
    catch (DllNotFoundException dnfe) 
    { 
    } 
    catch (Exception e) 
    { 
    } 
} 

protected override void OnStop() 
{ 
    try 
    { 
     DLLStop(); 
    } 
    catch (DllNotFoundException dnfe) 
    { 
    } 
    catch (Exception e) 
    { 
    } 
} 

基本上我們只是想用C++替換上述C#.NET Windows服務,以便我們的代碼完全在非託管環境中運行,而不是不必要地混淆用5行託管代碼執行此操作。

DLLStart()和DLLStop()是從我們的C +非託管的DLL,實際上啓動和停止的系統導入兩種功能。

我不完全確定什麼種類這將需要是爲了能夠做任何事情與泵或老實說。

希望這些額外的數據是非常有用的。

回答

2

我翻譯的C++代碼如下(未選中:)
PS:在同一個線程調用DLLStart,DLLStop會更可靠。

一個全局變量保存線程ID
DWORD threadID = 0;

在OnStart中相當於:
CreateThread(0, 0, PumpThread, 0, 0, 0);

在調用OnStop相當於:
PostThreadMessage(threadID, WM_QUIT, 0, 0);

線程程序:

DWORD WINAPI PumpThread(void* param) 
{ 
    threadID = GetCurrentThreadId(); 

    DLLStart(); 

    // create thread message queue 
    PeekMessage(&msg, 0, WM_USER, WM_USER, PM_NOREMOVE); 

    MSG msg; 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    DLLStop(); 
} 
+0

請注意,這是線程消息隊列。我不完全確定OP是否意識到消息被傳遞給線程,因此產生一個單獨的線程來處理傳入的消息是行不通的。 – 2011-06-14 09:41:21

+0

@Simon - 不知道我跟着你...你能擴張嗎? C#發射器肯定是在做我們想要的東西,但很可能我錯過了一些重要的東西:) – 2011-06-14 10:26:21

+0

非常感謝您抽出寶貴的時間,我們將會爲此付出努力,看看會發生什麼。 – 2011-06-14 10:27:30

3

在其最簡單的消息循環是這樣的:

MSG msg; 
while (GetMessage(&msg, NULL, 0, 0)) { 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

,但我不知道這確實解決了你的問題 - 你不能只是運行一個消息循環,任何地方,你看中的。所以我們需要更多的細節。

+1

你應該檢查'GetMessage()'返回'-1'來指示錯誤。 – sharptooth 2011-06-14 08:54:34

+0

@sharptooth我從來沒有見過這樣的事情發生。就我所知,唯一的辦法就是如果窗口句柄既非空也非無效,在上面的代碼中不是這種情況。 – 2011-06-14 09:06:26

+0

@sharptooth是正確的,這就是MSDN所說的,但實際上@niel的方式很好 – 2011-06-14 09:19:32

1

你必須創建一個用戶界面線程。工作線程沒有消息泵

看一看CWinThread

+1

這是不準確的。任何線程都可以創建消息隊列並將其抽出。 – 2011-06-14 09:20:19

+0

是的,UI線程是一個抽取消息的線程。一旦你創建了一個泵,或者像COM一樣創建一個泵,它就是一個UI線程。 – Coder 2011-06-14 11:22:12