在启动线程之前,在堆上分配一个结构,为错误返回参数留出空间。通过 CreateThread 的 lpParameter 参数将其传递给线程。在终止之前,请在此处留下您的错误代码。
然后只需记住结构在等待该线程的任何线程中的位置,并从中读取结果。
例如:
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);