未加星标

Getting Write Access to CString’s Internal Buffer

字体大小 | |
[系统(windows) 所属分类 系统(windows) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

In theMSDN Magazine article “Using STL Strings at Win32 API Boundaries” , I discussed how to use std::wstring with Win32 APIs.

Note: The aforementioned article focuses onstd::wstring containing Unicode UTF-16 encoded text; if you are interested in how to convert between an UTF-8 std::string and an UTF-16 std::wstring, this other MSDN Magazine article “Unicode Encoding Conversions with STL Strings and Win32 APIs” can come in handy.

But if you are developing (or maintaining) windows C++ applications using ATL, WTL or MFC, you already have a convenient string class available for use at the Win32 API boundary: CString .

CString is designed in a way to be very well integrated with Win32 APIs. For example, you can simply pass instances of CString to Win32 APIs taking input string pointers; in other words, CString is a drop-in replacement forLPCTSTR parameters.

Moreover, using CString you can easily load strings from resources (via its LoadString method ),format strings in a printf-like way using Format , or in a more advanced form using FormatMessage , etc.

Of course std::wstring has other advantages , like SSO (Small String Optimization), move semantics, STL iterator semantics, working with C++11 range-for loops, good integration with Boost, etc.

If you use ATL, WTL or MFC , many Win32 C-interface APIs are wrapped in a convenient object-oriented interface , and you can simply retrieve strings in CString instances (for example, calling a proper overload of CWindow::GetWindowText ).

But what if you want to get a string from a Win32 API that isn’t wrapped in a nice way by the existing ATL/WTL/MFC classes?

In this case, you may need to let the Win32 API to scribble its output in the CString’s internal string buffer . With STL’s wstring you can simply call the wstring::resize method to make enough room in the string, and then pass a pointer to that buffer, as described in the aforementioned MSDN Magazine article .

But how can you access CString’s internal buffer for writing ?

Well, you can call a couple of methods of the CString class: GetBuffer and ReleaseBuffer . The usage pattern is as follows:

Call CString::GetBuffer to allocate a sufficiently large internal buffer; on success, this method returns a non-const pointer to the allocated buffer, giving you write access to it. Call the Win32 API (or whatever function) passing the pointer returned by CString::GetBuffer, so the called function can write its result text in the specified buffer. Call CString::ReleaseBuffer, which releases the access to CString’s internal buffer, so that the CString object can sync its state to the new buffer content.

Note that if the called function writes a NUL-terminator at the end of the string (as most Win32 APIs usually do), you can simply call CString::ReleaseBuffer, without passing any argument . In fact, in this case, the ReleaseBuffer method will simply scan the string stored in the CString’s internal buffer, until it finds the terminating NUL.

In addition, you can specify an explicit string length value to CString::ReleaseBuffer. In this case, the string in the internal buffer will be considered for that exact length.

Note that in Unicode builds those lengths are expressed in wchar_ts (not in bytes!).

This commented C++ sample code shows CString’s GetBuffer and ReleaseBuffer in action:

CString s;
// Allocate an internal buffer for CString,
// and get write access to it.
const int bufferSize = 100; // Size in wchar_ts!
wchar_t* buffer = s.GetBuffer(bufferSize);
// Scribble in the CString's internal buffer.
wcscpy_s(buffer, bufferSize, L"Connie");
// Release access to the internal buffer.
// Now the CString object synchronizes its state
// with the content of its internal buffer.
//
// NOTE: This assumes that the string in the buffer
// is *NUL*-terminated!
s.ReleaseBuffer();
// Avoid dangling references.
// After calling CString::ReleaseBuffer
// we cannot touch the CString's internal
// buffer anymore.
buffer = nullptr;
// Let's check if it works!
ATLASSERT(s == L"Connie");

Note that if you explicitly pass a string length to CString::ReleaseBuffer, the string in the internal buffer is truncated at the specified position; e.g. if you call “s.ReleaseBuffer(3);” only the first three characters in the CString’s internal buffer are considered for the final CString’s text, making s == “Con” in the example above.

P.S.Pay attention when you manipulate CString’s internal buffers. For example, note that CString is not designed to store strings with embedded NULs. In fact, as stated in this MSDN documentation web page ( emphasis mine ):

“Although it is possible to create CStringT instances that contain embedded null characters, we recommend against it . Calling methods and operators on CStringT objects that contain embedded null characters can produce unintended results. ”

本文系统(windows)相关术语:三级网络技术 计算机三级网络技术 网络技术基础 计算机网络技术

主题: STLSDNC++WindowsUTSSE
分页:12
转载请注明
本文标题:Getting Write Access to CString’s Internal Buffer
本站链接:http://www.codesec.net/view/481377.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(windows) | 评论(0) | 阅读(36)