グローバル変数に有効なデータが必要ですQObject *p
。ただし、関数内でこの変数に何かを割り当てることは、関数のスコープ内で機能しますが、関数が戻った後、グローバルp
であってもNULLに戻されますp
。これが私のコードです:
#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
は、であるため、自身をに初期化します。したがって、になります。ただし、完全に異なるメモリアドレスで戻ると、スコープに戻ります。広範囲にわたるデバッグと頭痛の種の後の解決策は、パラメーターとしてを取り、それをの代わりにに渡すクラスメンバー関数を作成することです。その関数に渡すものはすべて、DLLが持続する必要がある限り持続する必要があります。または、ディープコピーを実行する独自のコピーコンストラクターを作成できます。install
mParent
QObject
NULL
p
NULL
this
install
QObject
install
this