WinRT _really_是否支持线程本地存储功能(Tls *)?

时间:2015-01-15 17:01:13

标签: windows-runtime

我将旧版Windows代码移植到Windows运行时(WinRT),特别是Windows Phone 8.1。该代码包含对线程本地存储函数的调用,如TlsAlloc,TlsFree,TlsGetValue和TlsSetValue。根据MSDN的"Win32 and COM for Windows Runtime apps (system)"页面,WinRT支持这四种TLS功能。例如,阅读TlsAlloc documentation,其中一个读取:

  

Windows Phone 8.1 :Windows Phone应用商店支持此功能   Windows Phone 8.1及更高版本上的应用程序。当一个Windows Phone Store应用程序   调用此函数,它将替换为对FlsAlloc的内联调用。   有关功能文档,请参阅FlsAlloc。

当我在遗留代码中#include指示的头文件Processthreadsapi.h时,编译失败:

  

错误C2039:' TlsAlloc' :不是“全局命名空间”'

的成员

检查Processthreadsapi.h显示了它无法帮助我的原因:

/***********************************************************************************
*                                                                                  *
* 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) */
. . .

问题很明显:WinRT属于WINAPI_PARTITION_APP的世界,而不属于WINAPI_PARTITION_DESKTOP。因此,当我为WinRT编译我的应用程序时,我没有得到任何这些符号和函数声明。

这只是一个Windows头问题,MS应该包含WinRT的Tls *函数吗?或者WinRT不支持线程本地存储,与文档相反?

3 个答案:

答案 0 :(得分:1)

是的,确实如此。从c:\ Program Files(x86)\ Windows Phone Kits \ 8.1 \ Include \ minwin \ processthreadsapi.h,第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..

您描述的文件是文件的8.0版本。当然不知道这是怎么发生的。也许你有一个早期测试版,也许你复制文件来解决问题。登陆页面is here,我确实下载了8.1 Update 1模拟器,但不知道是否还更新了SDK标头。

答案 1 :(得分:1)

这仅在VS 2013 Update 4中添加。如果您有早期安装(包括Update 4 RC),则您将无法获得更新的标头。

答案 2 :(得分:0)

另一种选择是__declspec(线程),它可能更容易使用。它可能映射到相同的功能。