2012-08-15 96 views
0

我想從本機dll中創建的線程回調到託管包裝,我成功創建了我的線程並通過Qt.s框架信號和插槽。從非託管dll中的QThread回調到託管C++主線程

如何從一個單獨的線程回調非託管和受管dll之間的主線程?非託管是在QT C++和託管通過VS C++完成的。

非託管的DLL: 的main.cpp

typedef void (__stdcall * processCallback)(char*, int, int); 
Thread* thread; 
EXTEXPORT_VOID initdll(processCallback callback) 
{ 
    /* Init MainThread - Runs eventloop */ 
    thread = new Thread(callback); 
    thread ->start(); 
} 

thread.h - run方法,使我的回調在這裏,但回調繼續在我的新的線程,而不是創建它的主線程我管理的DLL。爲什麼?

void run() { 
    callback("Testing callback", 0, 0); 
    exec(); 
} 

我需要這個回調是我的主線程,而不是在我現在runningthread。

託管DLL

/* From unmanaged to managed c++ */ 
[UnmanagedFunctionPointerAttribute(CallingConvention::StdCall)] 
public delegate void UnmanagedCallbackDelegate(char*, int, int); 

typedef void (__stdcall * typeCallback)(char*, int, int); //Same def as in Unm. dll 
public ref class cDLLThreadWrapper 
{ 
    [DllImport("cDLL.dll", CallingConvention=CallingConvention::StdCall)] 
    static void initdll(typeCallback); 

public: 
    typeCallback callbackNative; 
    UnmanagedCallbackDelegate^ m_CallbackDelegate; 

    cDLLThreadWrapper() 
    { 

    } 
    void init() 
    { 
     m_CallbackDelegate = gcnew UnmanagedCallbackDelegate(this, &cDLLThreadWrapper::UnhandledCallback); 
     IntPtr ptr = Marshal::GetFunctionPointerForDelegate(m_CallbackDelegate); 
     callbackNative = static_cast<typeCallback>(ptr.ToPointer()); 

     initdll(callbackNative); 
    } 
      void UnhandledCallback(char* data, int x, int y) 
    { 
     String^ callStr = gcnew String(data); 
        //AppDomain.GetCurrentThreadId()) 
     //I get here but the thread is wrong, it should be the main thread 
        //which called the initdll function from this wrapper. 
    } 
} 

正如我所說的回調作品,但我把它在錯誤的線程出於某種原因,不應該回調是從線程1 - >主線程?

這是一個非常簡單的例子,但具體的問題是爲什麼我的回調不會從我新創建的線程去主線程,而是留在新創建的線程。我在哪裏想錯了?任何幫助感謝!

+0

這聽起來像你混合回調的概念和事件循環 - 'thread1'調用函數,使代碼在執行' thread1'。 Qt線程有[事件循環](http://doc.qt.nokia.com/qq/qq14-threading.html#perthreadeventloops) - 你的主線程有類似的東西嗎?您想要將事件發佈到循環,而不是簡單地使用回調函數。 – tmpearce 2012-08-15 13:50:27

+0

我注意到我沒有提到這一點,我已經在.net窗體應用程序中引用了我的包裝器DLL,應用程序事件循環是我在這件事情上的「主線程」。我知道如何在兩個qt線程之間使用信號和插槽,但問題是當我需要通過我的C++包裝器從非託管線程dll到我的.net窗體應用程序時。我如何將事件發佈到我的qt dll的.net事件循環中,這真的是我的問題? – 2012-08-15 14:14:46

回答

1

你正在執行你的回調作爲一個直接調用,你有什麼驚喜?如果你在Qt中做callback(...),它會在你的新線程中執行並繼續。這相當於宣佈與Qt::DirectConnection類型的信號插槽連接。 Qt很聰明,當你調用者線程和目標線程不同時,你會在幕後爲你做點什麼。但爲了自動工作,源必須聲明爲signal,目標必須聲明爲slot,並且目標必須是QThread,具有運行Qt特定的事件循環。你有一些事件循環運行在託管的C++中,但Qt不知道如何以及如何發佈。絕對不是QObject元數據,你的.NET C++將無法理解它。 Qt魔術只能在Qt中使用。您必須瞭解特定的事件是如何發佈到您的.NET C++並教您的Qt代碼來完成的。我不是.NET專家,但下面看起來有用

How to map Qt Signal to Event in Managed C++ (C++/CLI)

+0

是的,我注意到,當然,感謝您的鏈接,看起來很有希望。我注意到我可以通過在我的.net窗體應用程序中調用代理以另一種方式來實現,但我明白了你的觀點。 – 2012-08-15 15:04:15