我想从一个在本地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 - 运行方法,我在这里进行回调,但回调在我的新线程中继续,而不是在我的托管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 - &gt;主线?
这是一个非常简化的示例,但具体问题是为什么我的回调不会从我新创建的线程转到主线程,而是保留在新创建的线程中。我错在哪里?任何帮助表示赞赏!
答案 0 :(得分:1)
您正在直接通话中执行回叫,令您感到惊讶的是什么?如果您在Qt中执行callback(...)
,它将在您的新线程中执行并继续。它相当于声明与Qt::DirectConnection
类型的信号槽连接。当调用者线程和目标线程不同时,Qt很聪明并为你做幕后Qt::QueuedConnection
。但为了使其自动工作,源必须声明为signal
,目标必须声明为slot
,目标必须是QThread
,具有Qt特定的事件循环运行。您在托管C ++中运行了“某个”事件循环,但Qt不知道如何以及在那里发布什么。绝对不是QObject
元数据,您的.NET C ++将无法理解它。 Qt魔法仅在Qt内部起作用。您必须了解如何将特定事件发布到.NET C ++并教您的Qt代码来执行此操作。我不是.NET专家,但以下内容看起来很有用