在幫公司修改舊程式的時候發現 WriteFile() 結束後出現一大堆空白符號,到底是怎麼回事?

議題原因

這份 Code 是已經定義為 Unicode 的格式,所以相關功能都是用 TCHAR 來進行,
雖然傳入變數已經型別轉換過,但是寫入之前還必須要再轉回來才可以。

找方法

在網路上找看看有沒有跟我一樣的苦主,發現這一篇。 为什么 WriteFile 写文件中间好多空格
文章之精采大家都沒有辦法提出解法,最後原 PO 自行破關讓人感到佩服,讚讚。
不過還是來看一下這個東西的用法。

USES_CONVERSION;
DWORD cb = strlen(T2A(msg)) * sizeof *T2A(msg);
WriteFile(h,T2A(msg), cb, &cb, 0);

看起來簡單但是直覺重點應該放在 T2A(msg)

#define T2A W2A
#define W2A(lpw) (\
	((_lpw = lpw) == NULL) ? NULL : (\
	(_convert = (static_cast<int>(wcslen(_lpw))+1), \
	(_convert>INT_MAX/2) ? NULL : \
	ATLW2AHELPER((LPSTR) alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp))))

這段 Code 看起來要特別注意 alloca,所以使用上要避免把這個東西放在 loop 裡面,不然記憶體很快就會不見了。
最好也是把這個寫成獨立 function 避免出問題。

實作

看完使用前說明書後就可以愉快使用啦!

如果不想使用 macro 也可以自己寫一個轉換功能。

//Function that safely converts a 'WCHAR' String to 'LPSTR':
char* ConvertLPWSTRToLPSTR(LPWSTR lpwszStrIn)
{
	LPSTR pszOut = NULL;
	if (lpwszStrIn != NULL)
	{
		int nInputStrLen = wcslen(lpwszStrIn);

		// Double NULL Termination
		int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
		pszOut = new char[nOutputStrLen];

		if (pszOut)
		{
			memset(pszOut, 0x00, nOutputStrLen);
			WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
		}
	}
	return pszOut;
}

印出來的東西正常看起來就是賞心悅目~

參考網站


此文章採用 CC BY-SA 4.0 協議 ,轉貼請標註出處,乾蝦乾蝦~

如何利用 Github Pages 架設 Hexo Blog 下一篇