Windows runtime WinRT真的支持线程本地存储函数(Tls*)吗?

Windows runtime WinRT真的支持线程本地存储函数(Tls*)吗?,windows-runtime,Windows Runtime,我正在将遗留的Windows代码移植到Windows运行时(WinRT),特别是Windows Phone 8.1。代码包含对线程本地存储函数(如TlsAlloc、TlsFree、TlsGetValue和TlsSetValue)的调用。根据MSDN的页面,WinRT支持这四个TLS函数。例如,阅读以下内容: Windows Phone 8.1:Windows Phone应用商店支持此功能 Windows Phone 8.1及更高版本上的应用程序。当Windows Phone应用商店应用程序 调用

我正在将遗留的Windows代码移植到Windows运行时(WinRT),特别是Windows Phone 8.1。代码包含对线程本地存储函数(如TlsAlloc、TlsFree、TlsGetValue和TlsSetValue)的调用。根据MSDN的页面,WinRT支持这四个TLS函数。例如,阅读以下内容:

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

当我在遗留代码中包含指示的头文件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分区应用程序的世界,而不是WINAPI分区桌面。因此,当我为WinRT编译我的应用程序时,我没有得到任何这些符号和函数声明


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

是的,确实如此。从c:\Program Files(x86)\Windows Phone Kits\8.1\Include\minwin\processthreadsapi.h第411行复制/粘贴:

//TlsAlloc、TlsFree、TlsGetValue和TlsSetValue定义为内联线
//仅适用于商店应用程序,不适用于桌面应用程序
#pragma区域应用程序系列
#如果WINAPI_分区_应用程序&&!WINAPI_分区_桌面
#包括
强制内联
_必须检查结果吗_
WINBASEAPI
德沃德
WINAPI
TlsAlloc(
无效的
)
{
返回FlsAlloc(空);
}
//等等。。

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

这仅在VS 2013更新4中添加。如果您有早期安装(包括Update 4 RC),则不会有更新的标题。

另一种方法是u declspec(线程),它可能更易于使用。它可能映射到相同的功能。

您只是查看了文件的错误部分。TlsAlloc()的WinRT版本出现在第403行。一个内联函数,它调用FlsAlloc()。当我尝试时,打电话也不是问题。只需
#include
即可。@HansPassant我们必须查看不同的头文件。在我的c:\Program Files(x86)\Windows Phone Kits\8.1\Include\minwin\processthreadsapi.h副本中,只有一次出现了“TlsAlloc”,这是我上面引用的部分。“FlsAlloc”根本不出现在文件中。第403行指向CreateProcessW函数声明。即使包括ing windows.h,VS的Intellisense也无法识别TlsAlloc。我做错了什么?很高兴知道我没有疯:-)。事实证明,我有Windows8.1SDK更新3,因此Peter Torr建议升级到更新4就可以了。非常感谢您的帮助性回复。非常感谢更新4的重要提示。这里有一个重要的教训需要学习:如果文档中说明支持某个功能,请确保您有最新的更新。再次感谢!
// 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..