va_list 32位和64位不相容
這兩天將程式移植到64位上,以下程式碼在32位linux上完全沒有問題,但是在64位linux上不能編譯通過:
std::vector<char*> vecCharVar;
......
INT32 nprint = vsnprintf(szQuery, sizeof(szQuery), strSQLFormat.c_str(), reinterpret_cast<va_list>(&vecCharVar[0]));
編譯時報錯:
cannot convert from char** to va_list
在網上查資料,才知道在64位下,va_list已經不是指標了,而是一個24位元組的結構體。搜了好多帖子,倒是有人和我遇到了完全一樣的問題:
網上有各種正確的分析,可以都沒有很簡便的解決方法。有人提到libffi庫可以解決這個問題:
我沒有去研究libffi,因為程式碼中應用很簡單,格式化字串中只有%s,所以手動寫了個函式組裝動態引數:
bool GetFormatDBStr(string &outStr, string strFormat, vector<const char *> &vecArg)
{
size_t iVecIdx = 0;
string::size_type iStart = 0, iPos;
iPos = strFormat.find("%s", iStart);
while(string::npos != iPos)
{
outStr += strFormat.substr(iStart, iPos - iStart);
if(iPos>iStart && '%'==strFormat.at(iPos-1)) // %前面有轉義字元
{
outStr += strFormat.substr(iPos, 2);
}
else
{
if(iVecIdx >= vecArg.size() || NULL == vecArg[iVecIdx])
{
return false;
}
outStr += vecArg[iVecIdx];
iVecIdx++;
}
iStart = iPos + 2;
iPos = strFormat.find("%s", iStart);
}
if(iStart < strFormat.size())
{
outStr += strFormat.substr(iStart, strFormat.size() - iStart);
}
return iVecIdx == vecArg.size();
}
程式碼從32位移植到64位,比較簡單,可是還是會遇到各種問題。引用帖子中一個老外的回覆:
You may take it that I was surprised to find this much discrepancy between the 32-bit and 64-bit versions.