我相信,通过查看this文章,我可以安全地使用CStrings来存储某些Windows API函数的返回字符串结果。
例如,我可以执行以下操作(不是我的代码,来自我上面链接的文章):
//GetCurrentDirectory gets LPTSTR
CString strCurDir;
::GetCurrentDirectory(MAX_PATH, strCurDir.GetBuffer(MAX_PATH));
strCurDir.ReleaseBuffer();
GetCurrentDirectory以“常规”方式分配数据。我知道我也可以使用STL wstring来做到这一点。
现在我的问题是,我可以安全地这个吗?
int main()
{
CString profileRootPath;
HRESULT result = SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, (PWSTR*)&profileRootPath);
wcout << profileRootPath.GetString();
profileRootPath.ReleaseBuffer();
Sleep(10000);
return 0;
}
根据SHGetKnownFolderPath的MSDN页面,SHGetKnownFolderPath输出的数据需要通过调用CoTaskMemFree来取消分配。由于这个原因,对ReleaseBuffer的调用是否无效?或者这会正常工作吗?在这种情况下使用任何字符串类并且只使用普通的C样式数组来保存数据,然后在数组上使用CoTaskMemFree是不是一个好主意?如果代码无效,那么最正确的方法是什么?
答案 0 :(得分:2)
使用ATL,代码片段可能非常简单:
CComHeapPtr<WCHAR> pszPath;
HRESULT result = SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, (PWSTR*) &pszPath);
CString sPath(pszPath);
wcout << sPath.GetString();
~CComHeapPtr
将CoTaskMemFree
超出范围,CString
构造函数会将值设为const WCHAR*
。
如果没有CComHeapPtr
,您可以这样做:
WCHAR* pszPath = nullptr;
HRESULT result = SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, (PWSTR*) &pszPath);
CString sPath(pszPath);
CoTaskMemFree(pszPath);
wcout << sPath.GetString();
GetCurrentDirectory
只需要将内存指针存储到字符串中,因此使用堆栈变量是有意义的,因为它没有初始化和清理成本。如果你需要一个字符串,你可以从堆栈字符数组构建它 - 这消除了ReleaseBuffer
调用中的必要性:
TCHAR pszPath[MAX_PATH];
GetCurrentDirectory(_countof(pszPath), pszPath);
CString sPath(pszPath);
答案 1 :(得分:0)
我的问题的答案完全没有,我认为这是,因为CoTaskMemAlloc是一种分配内存的特殊方式。我只是坚持常规做事。
int main()
{
WCHAR* profileRootPath = nullptr;
HRESULT result = SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &profileRootPath);
wcout << profileRootPath;
CoTaskMemFree(profileRootPath);
Sleep(10000);
return 0;
}