我需要有效数据在全局变量QObject *p
中。但是,在函数内部为该变量分配任何东西都在函数的范围内起作用,但是在函数返回后p
,即使p
是全局的,也会被设置回 NULL。这是我的代码:
#include ... // various includes
// p is NULL
QObject *p;
HHOOK hhk;
BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved)
{
return TRUE;
}
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT *mouseInfo = (MOUSEHOOKSTRUCT*)lParam;
QMouseEvent::Type type;
QPoint pos = QPoint(mouseInfo->pt.x, mouseInfo->pt.y);
Qt::MouseButton bu;
Qt::MouseButtons bus;
Qt::KeyboardModifiers md = Qt::NoModifier;
... // very large switch statement
// here is where i need some valid data in p
QCoreApplication::postEvent(p, new QMouseEvent(type, pos, bu, bus, md));
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
// note: MOUSEHOOKSHARED_EXPORT is the same as __declspec(dllexport)
// this function is called by the application that loads the dll
extern "C" MOUSEHOOKSHARED_EXPORT void install(QObject *mParent, DWORD threadID, HINSTANCE hInst)
{
p = mParent; // p is assigned here and keeps the value of mParent untill the function returns
hhk = SetWindowsHookEx(WH_MOUSE, MouseProc, hInst, threadID);
} // after this function returns, p is NULL
extern "C" MOUSEHOOKSHARED_EXPORT void uninstall()
{
UnhookWindowsHookEx(hhk);
}
我尝试了各种数据结构“解决方法”,例如使用struct
typedef
等……我似乎无法让它工作。我只需要p
保留mParent
.
编辑:这是我执行 install() 的地方
// EarthWidget is a class that is derived from QWidget(which is derived from QObject)
void EarthWidget::LoadAll()
{
HINSTANCE DLLinst = LoadLibrary("MouseHook.dll");
... // get functions in DLL using GetProcAddress & typedefs, etc...
// i pass in 'this' as mParent
install(this, GetWindowThreadProcessId((HWND)earthplugin->GetRenderHwnd(), NULL), DLLinst);
// note that GetWindowThreadProcessId does work and does return a valid thread id, so no problem there
}
编辑:找出问题所在。指针在执行this
时超出范围install
,因此mParent
,作为 a QObject
,将自身初始化为NULL
。从而p
变成NULL
。但是,返回时会在完全不同的内存地址处返回this
范围。install
经过大量调试和头疼之后,解决方案是创建一个类成员函数,该函数将 aQObject
作为参数并将其传递给install
而不是this
. 只要您需要 DLL 持续存在,您传递给该函数的任何内容都必须持续存在。那,或者,您可以创建自己的复制构造函数来执行深度复制。