Решение судя по всему кросс-компиляторное.
Что кинуть исключение в другом потоке (и вообще как метод одноразовой передачи сообщения потоку)
template <typename _type_exception>
void _throw_remote_proc(_type_exception * exception_object)
{
throw exception_object;
}
//
template <typename _type_exception>
__declspec(noreturn) void throw_remote(DWORD thread_id, _type_exception * exception_object)
{
HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, thread_id);
SuspendThread(hThread);
CONTEXT context;
ZeroMemory(&context, sizeof(context));
context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hThread, &context);
context.Eip = (DWORD)((void(*)(_type_exception *))&_throw_remote_proc<_type_exception>);
*((DWORD *)context.Esp) = (DWORD)exception_object;
context.Esp -= 4;
SetThreadContext(hThread, &context);
ResumeThread(hThread);
CloseHandle(hThread);
}
тест
class ex
{
public:
int data;
public:
ex(): data(0)
{
}
ex(int _data): data(_data)
{
}
};
//
bool ready = false;
//
DWORD CALLBACK ThreadProc(LPVOID lpParam)
{
ready = true;
try
{
for(;;)
{
Sleep(1);
}
}
catch (ex * e)
{
// Попадаем сюда, то есть всё работает
int x = e->data;
delete e;
}
ready = true;
return 0;
}
//
int main(int argc, char * argv[])
{
DWORD thread_id;
CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, &thread_id));
while (!ready)
{
Sleep(1);
}
ex * e = new ex(10);
ready = false;
throw_remote(thread_id, e);
while (!ready)
{
Sleep(1);
}
return 0;
}
Мне такое удобно делать, чтоб остановить поток слушающий сокет, потому что message-queue там нету и по-другому сообщение не передать.