2012-08-15 72 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