boost::thread支持XP SP2

Windows上使用std::thread对XP SP2有兼容问题,调用了系统API:GetLogicalProcessorInformation

可以使用boost::thread解决,boost::thread编译需加上支持XP宏定义

b2 release define=BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WINXP

 

boost has dropped winxp support by default. However, it does offer option to allow binary to run on winxp.
We followed the options on http://www.boost.org/users/history/version_1_60_0.html , and the compiled binaries can run on winxp sp3. Sadly, not including winxp sp2.

Let’s take a look at the build instruction:

This release of Boost will by default compile for Windows Vista/Windows Server 2008, if the compiler supports a recent enough Windows SDK, and for Windows XP otherwise. Binaries compiled with default options may not run on the older Windows versions.

It is still possible to explicitly specify target Windows version by defining BOOST_USE_WINAPI_VERSION to a numeric version of Windows API. For example, building Boost for Windows XP can be done with the following command:

b2 release define=BOOST_USE_WINAPI_VERSION=0x0501

But the compiled binaries will get following error when running on winxp sp2.

The procedure entry point GetLogicalProcessorInformation could not be located in the dynamic link library KERNEL32.dll.

Use IDA to disassemble the binary, we can see it’s due to boost::thread::hardware_concurrency()
Here is its implement:

    unsigned thread::physical_concurrency() BOOST_NOEXCEPT
{
// a bit too strict: Windows XP with SP3 would be sufficient
#if BOOST_PLAT_WINDOWS_RUNTIME                                    \
|| ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) \
|| ( ( defined(__MINGW32__) && !defined(__MINGW64__) ) && _WIN32_WINNT < 0x0600)
return 0;
#else
unsigned cores = 0;
DWORD size = 0;

GetLogicalProcessorInformation(NULL, &size);
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
return 0;

std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size);
if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE)
return 0;

const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);

for (size_t i = 0; i < Elements; ++i) {
if (buffer[i].Relationship == RelationProcessorCore)
++cores;
}
return cores;
#endif
}

 

if we put #pragma message in front of if-conditional statement, BOOST_USE_WINAPI_VERSION  = 0x0501 while BOOST_WINAPI_VERSION_WINXP is BOOST_WINAPI_VERSION_WINXP, a bit wired.

So the solution is

define=BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WINXP

instead of the suggestion from boost official website:

define=BOOST_USE_WINAPI_VERSION=0x0501

Verified with IDA:

.text$mn:0000106C ; unsigned int __cdecl boost::thread::physical_concurrency()
.text$mn:0000106C                 public ?physical_concurrency@thread@boost@@SAIXZ
.text$mn:0000106C ?physical_concurrency@thread@boost@@SAIXZ proc near
.text$mn:0000106C                 push    ebp
.text$mn:0000106D                 mov     ebp, esp
.text$mn:0000106F                 xor     eax, eax
.text$mn:00001071                 pop     ebp
.text$mn:00001072                 retn
.text$mn:00001072 ?physical_concurrency@thread@boost@@SAIXZ endp

It has become an empty function. The problem has been solved!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值