Does WinRT _really_ support thread local storage functions (Tls*)?

会有一股神秘感。 提交于 2020-01-15 09:10:59

问题


I'm porting legacy Windows code to Windows Runtime (WinRT), specifically Windows Phone 8.1. The code contains calls to thread local storage functions like TlsAlloc, TlsFree, TlsGetValue, and TlsSetValue. According to MSDN's "Win32 and COM for Windows Runtime apps (system)" page, these four TLS functions are supported under WinRT. Reading the TlsAlloc documentation, for example, one reads:

Windows Phone 8.1: This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later. When a Windows Phone Store app calls this function, it is replaced with an inline call to FlsAlloc. Refer to FlsAlloc for function documentation.

When I #include the indicated header file, Processthreadsapi.h, in my legacy code, the compile fails:

error C2039: 'TlsAlloc' : is not a member of '`global namespace''

Examining Processthreadsapi.h shows why it doesn't help me:

/***********************************************************************************
*                                                                                  *
* processthreadsapi.h -- ApiSet Contract for api-ms-win-core-processthreads-l1     *
*                                                                                  *
* Copyright (c) Microsoft Corporation. All rights reserved.                        *
*                                                                                  *
***********************************************************************************/
. . .
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
. . .
#ifndef FLS_OUT_OF_INDEXES
#define FLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
#endif

#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)

_Must_inspect_result_
WINBASEAPI
DWORD
WINAPI
TlsAlloc(
    VOID
    );


WINBASEAPI
LPVOID
WINAPI
TlsGetValue(
    _In_ DWORD dwTlsIndex
    );


WINBASEAPI
BOOL
WINAPI
TlsSetValue(
    _In_ DWORD dwTlsIndex,
    _In_opt_ LPVOID lpTlsValue
    );


WINBASEAPI
BOOL
WINAPI
TlsFree(
    _In_ DWORD dwTlsIndex
    );
. . .
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
. . .

The problem is clear: WinRT belongs to the world of WINAPI_PARTITION_APP, not WINAPI_PARTITION_DESKTOP. Therefore, when I compile my app for WinRT, I do not get any of these symbols and function declarations.

Is this only a Windows header problem, where MS should have included the Tls* functions for WinRT? Or is thread local storage not supported for WinRT, contrary to the documentation?


回答1:


Yes, it truly does. Copy/pasted from c:\Program Files (x86)\Windows Phone Kits\8.1\Include\minwin\processthreadsapi.h, line #411:

// TlsAlloc, TlsFree, TlsGetValue and TlsSetValue are defined as inlines 
// only for the store apps, not for desktop apps
#pragma region Application Family
#if WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP

#include <fibersapi.h>

FORCEINLINE
_Must_inspect_result_
WINBASEAPI
DWORD
WINAPI
TlsAlloc(
    VOID
    )
{
    return FlsAlloc(NULL);
}
// etc..

The file that you describe is the 8.0 version of the file. No idea how this happened of course. Perhaps you have an early beta, perhaps you copied files to solve a problem. The landing page is here, I did download the 8.1 Update 1 emulators but don't know if that also updated the SDK headers.




回答2:


This is only added in VS 2013 Update 4. If you have an earlier install (including Update 4 RC) you won't have the updated headers.




回答3:


An alternative is __declspec(thread), which may be easier to use. It likely maps to the same functionality.



来源:https://stackoverflow.com/questions/27968850/does-winrt-really-support-thread-local-storage-functions-tls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!