1. 程式人生 > >va_list 32位和64位不相容

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.