我将旧版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不支持线程本地存储,与文档相反?
答案 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(线程),它可能更容易使用。它可能映射到相同的功能。