Winapi 转换boost::线程->;XP ThreadId的本机\u句柄()

Winapi 转换boost::线程->;XP ThreadId的本机\u句柄(),winapi,boost-thread,Winapi,Boost Thread,我已经通过使用GetThreadId(句柄)从boost::thread中成功地从本机\u句柄()中获取了Windows线程ID。遗憾的是,这个调用在Windows XP上不可用,在四处搜索之后,我找到了一个解决方案,通过WINAPI的Thread32First()和Thread32Next()函数遍历所有线程,从而为XP提供als回退支持 这在某种程度上确实有效,但我的问题是我目前只能识别进程的线程。。。我现在不知道如何从一侧将本机\u句柄()与循环遍历中相应的线程入口32匹配 THREADE

我已经通过使用GetThreadId(句柄)boost::thread中成功地从本机\u句柄()中获取了Windows线程ID。遗憾的是,这个调用在Windows XP上不可用,在四处搜索之后,我找到了一个解决方案,通过WINAPI的Thread32First()Thread32Next()函数遍历所有线程,从而为XP提供als回退支持

这在某种程度上确实有效,但我的问题是我目前只能识别进程的线程。。。我现在不知道如何从一侧将本机\u句柄()与循环遍历中相应的线程入口32匹配

THREADENTRY32 te32;
//...
do { 
    if( te32.th32OwnerProcessID == GetCurrentProcessId() ) {
        DWORD threadId = te32.th32ThreadID;
        printf( "\n     THREAD ID      = 0x%08X", te32.th32ThreadID ); 
    }
} while( Thread32Next(hThreadSnap, &te32 ) );
有人能帮我吗?如何在WindowsXP上将boost::thread->native_handle()转换为ThreadId


多谢各位

将循环中的每个线程ID传递给,直到找到匹配的
句柄。例如:

HANDLE hBoostThread = ...; // from boost::thread->native_handle()
DWORD dwBoostThreadID = 0;

THREADENTRY32 te32;
//...
do
{ 
    if( te32.th32OwnerProcessID == GetCurrentProcessId() )
    {
        HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
        if (hThread != NULL)
        {
            if (hThread == hBoostThread)
            {
                CloseHandle(hThread);
                dwBoostThreadID = te32.th32ThreadID; 
                break;
            }
            CloseHandle(hThread);
        }
    }
}
while( Thread32Next(hThreadSnap, &te32 ) );
为了更好地衡量,您可以将其封装在一个函数中,只要
GetThreadId()
本机不可用,就可以调用该函数,这样代码就不需要知道差异,例如:

DWORD WINAPI MyGetThreadId(HANDLE Thread)
{
    THREADENTRY32 te32;

    HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hThreadSnap == INVALID_HANDLE_VALUE)
        return 0;

    if (Thread32First(hThreadSnap, &te32))
    {
        do
        { 
            HANDLE hOpenThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
            if (hOpenThread != NULL)
            {
                if (hOpenThread == Thread)
                {
                    CloseHandle(hOpenThread);
                    CloseHandle(hThreadSnap);
                    return te32.th32ThreadID; 
                }

                CloseHandle(hOpenThread);
            }
        }
        while( Thread32Next(hThreadSnap, &te32 ) );
    }

    CloseHandle(hThreadSnap);
    return 0;
}

因此,更好的选择是直接查询目标线程自身的ID,而不是手动查找:

typedef long (WINAPI *LPFN_NTQIT)(HANDLE thread, int infoclass, void *buf, long size, long *used);

typedef struct _THREAD_BASIC_INFORMATION
{
    ULONG ExitStatus;
    void* TebBaseAddress;
    ULONG UniqueProcessId;
    ULONG UniqueThreadId;
    ULONG AffinityMask;
    ULONG BasePriority;
    ULONG DiffProcessPriority;
} THREAD_BASIC_INFORMATION;

DWORD WINAPI MyGetThreadId(HANDLE Thread)
{
    DWORD dwThreadId = 0;

    HMODULE hLib = LoadLibrary("ntdll.dll");
    if (hLib != NULL)
    {
        LPFN_NTQIT lpNtQueryInformationThread = (LPFN_NTQIT) GetProcAddress(hLib, "NtQueryInformationThread");

        if (lpNtQueryInformationThread != NULL)
        {
            THREAD_BASIC_INFORMATION tbi = {0};
            ULONG used = 0;

            if (lpNtQueryInformationThread(Thread, 0, &tbi, sizeof(tbi), &used) == 0)
                dwThreadId = tbi.UniqueThreadId;
        }

        FreeLibrary(hLib);
    }

    return dwThreadId;
}
DWORD dwThreadID = lpGetThreadId((HANDLE) boost::thread->native_handle());
typedef long (WINAPI *LPFN_NTQIT)(HANDLE thread, int infoclass, void *buf, long size, long *used);

typedef struct _THREAD_BASIC_INFORMATION
{
    ULONG ExitStatus;
    void* TebBaseAddress;
    ULONG UniqueProcessId;
    ULONG UniqueThreadId;
    ULONG AffinityMask;
    ULONG BasePriority;
    ULONG DiffProcessPriority;
} THREAD_BASIC_INFORMATION;

DWORD WINAPI MyGetThreadId(HANDLE Thread)
{
    DWORD dwThreadId = 0;

    HMODULE hLib = LoadLibrary("ntdll.dll");
    if (hLib != NULL)
    {
        LPFN_NTQIT lpNtQueryInformationThread = (LPFN_NTQIT) GetProcAddress(hLib, "NtQueryInformationThread");

        if (lpNtQueryInformationThread != NULL)
        {
            THREAD_BASIC_INFORMATION tbi = {0};
            ULONG used = 0;

            if (lpNtQueryInformationThread(Thread, 0, &tbi, sizeof(tbi), &used) == 0)
                dwThreadId = tbi.UniqueThreadId;
        }

        FreeLibrary(hLib);
    }

    return dwThreadId;
}