Перед запуском потока выделите структуру в куче с местом для параметров возврата ошибки. Передайте его потоку через аргумент lpParameter в CreateThread. До завершения оставьте там свои коды ошибок.
Тогда просто запомните расположение структуры в любом потоке, ожидающем этого потока, и прочитайте результаты оттуда.
Например:
struct threadinfo {
void *someArgument;
DWORD error_code;
int error_flag;
};
DWORD WINAPI threadproc(LPVOID arg) {
struct threadinfo *ti = (struct threadinfo *)arg;
// do things using ti->someArgument
ti->error_code = GetLastError();
ti->error_flag = 42;
return 0; // return code ignored
}
void start_and_wait() {
struct threadinfo *ti = (struct threadinfo *)malloc(sizeof(*ti));
ti->someArgument = &something;
HANDLE hThread = CreateThread(NULL, 0, threadproc, (LPVOID)ti, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
printf("Exit code %08x, flag %d\n", ti->error_code, ti->error_flag);
free((void*)ti);
}
Если вы разговариваете с удаленным потоком, один из вариантов может состоять в том, чтобы передать дескриптор сегмента общей памяти как lpParameter. Вы можете ввести дескриптор в удаленный процесс через DuplicateHandle
, а затем запустить поток. Затем поток может, прежде чем вернуться, отобразить сегмент совместно используемой памяти (если он еще этого не сделал), поместить свои результаты в сегмент совместно используемой памяти, затем удалить его и закрыть маркер.
Например, в удаленном процессе:
DWORD WINAPI threadproc(LPVOID arg) {
LPVOID shmem = MapViewOfFile((HANDLE)arg, FILE_MAP_ALL_ACCESS, 0, 0, 4096);
struct threadinfo *ti = (struct threadinfo *)shmem;
// do stuff
ti->error_code = GetLastError();
ti->error_flag = 42;
UnmapViewOfFile(shmem);
CloseHandle((HANDLE)arg);
return 0;
}
А в процессе вызова:
HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL);
LPVOID shmem = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 4096);
struct threadinfo *ti = (struct threadinfo *)shmem;
ti->someArgument = ...;
HANDLE remote_handle;
DuplicateHandle(GetCurrentProcess(), mapping, hRemoteProcess, &remote_handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, startAddress, remote_handle, 0, NULL);
WaitForSingleObject(hRemoteThread);
printf("err %08x flag %d\n", ti->error_code, ti->error_flag);
UnmapViewOfFile(shmem);
CloseHandle(mapping);