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. 或許可以試試下面這個方法//試了不行
-
// std::string -> std::wstring
-
std::string s("string");
-
std::wstring ws;
-
ws.assign(s.begin(), s.end());
-
-
// std::wstring -> std::string
-
std::wstring ws(L"wstring");
-
std::string s;
-
s.assign(ws.begin(), ws.end());
2.
第一種方法:調用WideCharToMultiByte()和MultiByteToWideChar(),代碼如下(關於詳細的解釋,可以參考《windows核心編程》):
-
-
-
using namespace std;
-
//Converting a WChar string to a Ansi string
-
std::string WChar2Ansi(LPCWSTR pwszSrc)
-
{
-
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
-
if (nLen<= 0) return std::string("");
-
char* pszDst = new char[nLen];
-
if (NULL == pszDst) return std::string("");
-
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
-
pszDst[nLen -1] = 0;
-
std::string strTemp(pszDst);
-
delete [] pszDst;
-
return strTemp;
-
}
-
string ws2s(wstring& inputws){ return WChar2Ansi(inputws.c_str()); }
-
//Converting a Ansi string to WChar string
-
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];
-
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];
-
wstring wcharString(pwszDst);
-
delete pwszDst;
-
return wcharString;
-
}
-
std::wstring s2ws(const string& s){ return Ansi2WChar(s.c_str(),s.size());}
第二種方法:采用ATL封裝_bstr_t的過渡:(注,_bstr_是Microsoft Specific的,所以下面代碼可以在VS2005通過,無移植性);
-
-
-
using namespace std;
-
-
string ws2s(const wstring& ws);
-
wstring s2ws(const string& s);
-
string ws2s(const wstring& ws)
-
{
-
_bstr_t t = ws.c_str();
-
char* pchar = (char*)t;
-
string result = pchar;
-
return result;
-
}
-
wstring s2ws(const string& s)
-
{
-
_bstr_t t = s.c_str();
-
wchar_t* pwchar = (wchar_t*)t;
-
wstring result = pwchar;
-
return result;
-
}
第三種方法:使用CRT庫的mbstowcs()函數和wcstombs()函數,平台無關,需設定locale。
-
-
-
using namespace std;
-
string ws2s(const wstring& ws)
-
{
-
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
-
setlocale(LC_ALL, "chs");
-
const wchar_t* _Source = ws.c_str();
-
size_t _Dsize = 2 * ws.size() + 1;
-
char *_Dest = new char[_Dsize];
-
memset(_Dest,0,_Dsize);
-
wcstombs(_Dest,_Source,_Dsize);
-
string result = _Dest;
-
delete []_Dest;
-
setlocale(LC_ALL, curLocale.c_str());
-
return result;
-
}
-
wstring s2ws(const string& s)
-
{
-
setlocale(LC_ALL, "chs");
-
const char* _Source = s.c_str();
-
size_t _Dsize = s.size() + 1;
-
wchar_t *_Dest = new wchar_t[_Dsize];
-
wmemset(_Dest, 0, _Dsize);
-
mbstowcs(_Dest,_Source,_Dsize);
-
wstring result = _Dest;
-
delete []_Dest;
-
setlocale(LC_ALL, "C");
-
return result;
-
}
//第四種方法,標准C++轉換方法:(待續)
//第五種方法,在C++中使用C#類庫:(待續
其中第四種,我的實現始終存在一些問題。第五種,我只是知道有這么一種方案,沒有時間去詳細了解,算是給一些提示吧。
