一般来说,我使用异常来处理错误,但是我在这里遇到的问题是错误适用于不同于导致错误的线程. 基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是
基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是,创建设备可能会失败,因此我需要在尝试创建实例的线程中抛出异常,而不是窗口代码
回调函数:
void Callback(HWND hwnd, boost::function<void(HWND,LPARAM)> call, LPARAM lParam) { //Make our stack allocated function object into a heap allocated one boost::function<void(HWND,LPARAM)> *callH = new boost::function<void(HWND,LPARAM)>(call); //send a message with a pointer to our function object in the WPARAM PostMessage(hwnd, WM_CALLBACK, (unsigned)callH, lParam); } LRESULT CALLBACK HookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { //check for our custom message if(msg == WM_CALLBACK) { //retreive the function pointer from the WPARAM boost::function<void(HWND,LPARAM)> *callH = (boost::function<void(HWND,LPARAM)>*)wParam; //call it (*callH)(hwnd,lParam); //delete our heap allocated function object delete callH; return 0; } else //if there was nothing relevant to us, call the old message procedure return CallWindowProc(hooked[hwnd], hwnd, msg, wParam, lParam); } //std::map<HWND, WNDPROC> hooked;
请求窗口线程创建设备的代码
Graphics::Graphics(IWindow *_window, Size2<unsigned> _size) :lost(false), reset(false), refCnt(0), backCol(0xFF000000), started(false), exited(false), window(_window), size(_size) { window->AddRef(); HWND hwnd = *((HWND*)window->GetHandle()); CallbackHook(hwnd); Callback(hwnd, boost::bind(&Graphics::create, this), 0); while(!started)Sleep(100); } void Graphics::create() { ...code that may throw various exceptions started = true; }
所以基本上我需要create()方法抛出的异常被创建Graphics对象的异常handelers捕获,这是另一个线程.
也许你可以使用 Boost.Exception将调用包装在另一个函数中.以下代码不起作用,但您可能会得到这个想法.
class Context { public: Context(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam) { // TODO: reroute call through Wrapper function. } void wait() { mutex::scoped_lock l(m); while (!finished) { c.wait(l); } if (ex) rethrow_exception(ex); } private: void Wrapper() { try { f(/*params*/); } catch (...) { ex = current_exception(); } mutex::scoped_lock l(m); finished = true; c.notify_all(); } boost::function<void(HWND,LPARAM)> f; exception_ptr ex; bool finished; mutex m; condition c; }; void Callback(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam) { Context ctx(hwnd, f, lParam); ctx.wait(); }