【发布时间】:2012-08-15 13:30:36
【问题描述】:
我想从在本机 dll 中创建的线程对我的托管包装器进行回调,我已经成功创建了我的线程并通过 Qt.s 框架信号和插槽进行了调用。
如何在非托管和托管 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();
}
我需要这个回调在我的主线程中,而不是在我现在正在运行的线程中。
托管 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.
}
}
正如我所说的回调有效,但由于某种原因我在错误的线程中得到它,回调不应该来自 thread1 -> 主线程吗?
这是一个非常简化的示例,但具体问题是为什么我的回调没有从新创建的线程转到主线程,而是留在新创建的线程中。我在哪里想错了?任何帮助表示赞赏!
【问题讨论】:
-
听起来你在混合回调和事件循环的概念——
thread1正在调用函数,所以代码在thread1中执行。 Qt 线程有event loops - 你的主线程有类似的东西吗?您想将事件发布到循环中,而不是简单地使用回调函数。 -
我注意到我没有提到这一点,我在 .net 表单应用程序中引用了我的包装器 dll,应用程序事件循环是我在这件事上的“主线程”。我知道如何在两个 qt 线程之间使用信号和槽,但问题是当我需要通过我的 c++ 包装器从我的非托管线程 dll 到我的 .net 表单应用程序时。如何从我的 qt dll 向我的 .net 事件循环发布事件,这真的是我的问题吗?
标签: c++ multithreading qt callback