string和wstring相互转换

VS2015+QT环境,加载dll函数loadlibrary,使用宽字符参数。路径有汉字总加载失败,于是先将汉字转化再加载dll,成功。

std::string ConvertUtf8ToGbk(const char* srcStr)
{
//utf-8转换为unicode
u32 dwStrLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)srcStr, -1, NULL, 0);
wchar_t * pwszGBK = new wchar_t[dwStrLen];
memset(pwszGBK, 0, dwStrLen);
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)srcStr, -1, pwszGBK, dwStrLen);

//unicode转为ansi
dwStrLen = WideCharToMultiByte(CP_ACP, 0, pwszGBK, -1, NULL, 0, NULL, NULL);
char* pchGBK = new char[dwStrLen + 1];
memset(pchGBK, 0, dwStrLen + 1);
WideCharToMultiByte(CP_ACP, 0, pwszGBK, -1, pchGBK, dwStrLen, NULL, NULL);

std::string szGbk = pchGBK;
delete[] pwszGBK;
delete[] pchGBK;
return szGbk;
}

std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
if (nSize <= 0) return NULL;
WCHAR *pwszDst = new WCHAR[nSize + 1];
memset(pwszDst, 0, nSize + 1);
if (NULL == pwszDst) return NULL;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize);
pwszDst[nSize] = 0;
if (pwszDst[0] == 0xFEFF) // skip Oxfeff
for (int i = 0; i < nSize; i++)
pwszDst[i] = pwszDst[i + 1];
std::wstring wcharString(pwszDst);
delete pwszDst;
return wcharString;
}

void CDllManage::LoadDll()
{
//加载univideocap.dll库
QString szPath = QCoreApplication::applicationDirPath();
szPath += "/univideocap.dll";
std::string szTemp = ConvertUtf8ToGbk(szPath.toStdString().c_str());
PrintLog(log_lv_debug, "路径: %s\n", szTemp.c_str());
std::wstring szDst = Ansi2WChar(szTemp.c_str(), szTemp.size());
if (false == szDst.empty())
{
m_hModule = LoadLibrary(szDst.c_str());
if (nullptr == m_hModule)
{
//qDebug() << "load dll fail, GetLastError:" << GetLastError() << endl;
PrintLog(log_lv_debug, "加载uniplaydll失败了:%d\n", GetLastError());
}
else
{
PrintLog(log_lv_debug, "加载成功了\n");
}
}
}

 

 

摘自:https://blog.csdn.net/layer781010/article/details/10224553

1. 或许可以试试下面这个方法//试了不行

  1.  
    // std::string -> std::wstring
  2.  
    std::string s("string");
  3.  
    std::wstring ws;
  4.  
    ws.assign(s.begin(), s.end());
  5.  
     
  6.  
    // std::wstring -> std::string
  7.  
    std::wstring ws(L"wstring");
  8.  
    std::string s;
  9.  
    s.assign(ws.begin(), ws.end());



2. 

随着VS2003升级到VS2005,很多以前熟悉的输入输出方式以及参数传递方式都不再有效(参看 vs2003 到vs2005代码升级要点http://bianyongtao.spaces.live.com/blog/cns!DD6CD3607CCE4603!214.entry )。其中根字符串相关的内容是,wcout不再有效,默认参数传递方式由char*改成了wchar_t*等几个方面。为了解决上面的这些问题,这篇文章里,我将给出几种C++ std::string和std::wstring相互转换的转换方法。
第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),代码如下(关于详细的解释,可以参考《windows核心编程》):
  1.  
    #include <string>
  2.  
    #include <windows.h>
  3.  
    using namespace std;
  4.  
    //Converting a WChar string to a Ansi string
  5.  
    std::string WChar2Ansi(LPCWSTR pwszSrc)
  6.  
    {
  7.  
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
  8.  
    if (nLen<= 0) return std::string("");
  9.  
    char* pszDst = new char[nLen];
  10.  
    if (NULL == pszDst) return std::string("");
  11.  
    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
  12.  
    pszDst[nLen -1] = 0;
  13.  
    std::string strTemp(pszDst);
  14.  
    delete [] pszDst;
  15.  
    return strTemp;
  16.  
    }
  17.  
    string ws2s(wstring& inputws){ return WChar2Ansi(inputws.c_str()); }
  18.  
    //Converting a Ansi string to WChar string
  19.  
    std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
  20.  
    {
  21.  
    int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
  22.  
    if(nSize <= 0) return NULL;
  23.  
    WCHAR *pwszDst = new WCHAR[nSize+1];
  24.  
    if( NULL == pwszDst) return NULL;
  25.  
    MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
  26.  
    pwszDst[nSize] = 0;
  27.  
    if( pwszDst[0] == 0xFEFF) // skip Oxfeff
  28.  
    for(int i = 0; i < nSize; i ++)
  29.  
    pwszDst[i] = pwszDst[i+1];
  30.  
    wstring wcharString(pwszDst);
  31.  
    delete pwszDst;
  32.  
    return wcharString;
  33.  
    }
  34.  
    std::wstring s2ws(const string& s){ return Ansi2WChar(s.c_str(),s.size());}


第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);
  1.  
    #include <string>
  2.  
    #include <comutil.h>
  3.  
    using namespace std;
  4.  
    #pragma comment(lib, "comsuppw.lib")
  5.  
    string ws2s(const wstring& ws);
  6.  
    wstring s2ws(const string& s);
  7.  
    string ws2s(const wstring& ws)
  8.  
    {
  9.  
    _bstr_t t = ws.c_str();
  10.  
    char* pchar = (char*)t;
  11.  
    string result = pchar;
  12.  
    return result;
  13.  
    }
  14.  
    wstring s2ws(const string& s)
  15.  
    {
  16.  
    _bstr_t t = s.c_str();
  17.  
    wchar_t* pwchar = (wchar_t*)t;
  18.  
    wstring result = pwchar;
  19.  
    return result;
  20.  
    }


第三种方法:使用CRT库的mbstowcs()函数和wcstombs()函数,平台无关,需设定locale。
  1.  
    #include <string>
  2.  
    #include <locale.h>
  3.  
    using namespace std;
  4.  
    string ws2s(const wstring& ws)
  5.  
    {
  6.  
    string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
  7.  
    setlocale(LC_ALL, "chs");
  8.  
    const wchar_t* _Source = ws.c_str();
  9.  
    size_t _Dsize = 2 * ws.size() + 1;
  10.  
    char *_Dest = new char[_Dsize];
  11.  
    memset(_Dest,0,_Dsize);
  12.  
    wcstombs(_Dest,_Source,_Dsize);
  13.  
    string result = _Dest;
  14.  
    delete []_Dest;
  15.  
    setlocale(LC_ALL, curLocale.c_str());
  16.  
    return result;
  17.  
    }
  18.  
    wstring s2ws(const string& s)
  19.  
    {
  20.  
    setlocale(LC_ALL, "chs");
  21.  
    const char* _Source = s.c_str();
  22.  
    size_t _Dsize = s.size() + 1;
  23.  
    wchar_t *_Dest = new wchar_t[_Dsize];
  24.  
    wmemset(_Dest, 0, _Dsize);
  25.  
    mbstowcs(_Dest,_Source,_Dsize);
  26.  
    wstring result = _Dest;
  27.  
    delete []_Dest;
  28.  
    setlocale(LC_ALL, "C");
  29.  
    return result;
  30.  
    }


//第四种方法,标准C++转换方法:(待续)
//第五种方法,在C++中使用C#类库:(待续
其中第四种,我的实现始终存在一些问题。第五种,我只是知道有这么一种方案,没有时间去详细了解,算是给一些提示吧。
posted @ 2019-05-15 11:05  damoying  阅读(3095)  评论(0编辑  收藏  举报