⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_understanding strings in com.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            <P style="MARGIN: 0in 0in 0pt">The original Microsoft engineers who 
            designed COM made a pretty courageous decision: They de facto 
            imposed Unicode to everyone in the 32-bit world at a time when the 
            original version of Windows NT was barely taking shape and the 
            doubled amount of RAM required to hold the same strings could easily 
            become problematic due to the high cost of memory. But the decision 
            proved advantageous, as it saved COM developers from having to 
            implement two variants of each interface (and relative coclasses 
            implementing it) just to deal with every possible type of client. 
            </P>
            <P style="MARGIN: 0in 0in 0pt">Now we have seen how to define a 
            COM-compliant character and by extension a COM-compliant string, but 
            we have not revealed yet how one can initialize such a string with a 
            string literal. The following statement: </P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt"><PRE>const OLECHAR* pComStr;</PRE><PRE>pComStr = "I love VCDJ and COM";</PRE></TD></TR></TBODY></TABLE>
            <P style="MARGIN: 0in 0in 0pt">does work in Windows 3.1x because 
            only ANSI strings exist there, but will fail to compile on Win32 and 
            Solaris because we are trying to copy an ANSI string to a Unicode 
            array of characters. The following form: </P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt"><PRE>const OLECHAR* pComStr;</PRE><PRE>pComStr = L"I love VCDJ and COM";</PRE></TD></TR></TBODY></TABLE>
            <P style="MARGIN: 0in 0in 0pt">will give the exact opposite results: 
            working on Win32, incorrect on Windows 3.1. What we really need is a 
            way to define the type of a string irrespective of the platform. 
            Nothing could fit the bill better than a macro, as in the code 
            below: </P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt"><PRE>const OLECHAR* pComStr;</PRE><PRE>pComStr = OLESTR("I love VCDJ and COM");</PRE></TD></TR></TBODY></TABLE>
            <P style="MARGIN: 0in 0in 0pt">The <I>OLESTR()</I> macro is 
            translated differently depending on the target of the build process, 
            so we obtain the correct definition in all cases. Wtypes.h reports 
            it as follows, with some secondary adjustments made to clarify the 
            original code: </P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt"><PRE>#if defined(_WIN32) &amp;&amp; !defined(OLE2ANSI)</PRE><PRE>#define OLESTR(str) L##str</PRE><PRE>#else</PRE><PRE>#define OLESTR(str) str</PRE><PRE>#endif</PRE></TD></TR></TBODY></TABLE>
            <P class=MsoNormal><SPAN 
            style="DISPLAY: none; FONT-FAMILY: Arial; FONT-SIZE: 9pt; mso-hide: all">&nbsp;<o:p></o:p></SPAN></P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt">
                  <P class=MsoNormal><I><SPAN 
                  style="FONT-FAMILY: Arial; FONT-SIZE: 9pt">Note: In all other 
                  Win32 API implementations there is a discrepancy between 
                  Windows 95 / Windows 98 and Windows NT's string treatment, 
                  since the former employs one-byte ANSI characters and the 
                  latter internally works only with two-byte Unicode characters. 
                  However, when it comes to COM, both operating systems agree on 
                  the use of Unicode strings. </SPAN></I><SPAN 
                  style="COLOR: black; FONT-FAMILY: Arial; FONT-SIZE: 9pt"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE>
            <P style="MARGIN: 0in 0in 0pt">At this point you may be curious as 
            to why the data type was called OLECHAR rather than the more obvious 
            COMCHAR. The answer to this question has its roots partly in history 
            and partly in marketing: until a few years ago OLE2, the main family 
            of technologies relying on the COM foundation, was deemed more 
            important than COM itself, hence the acronym OLE spread everywhere. 
            The later change of marketing orientation could not be reflected in 
            the symbol names to avoid breaking a lot of existing and correctly 
            functioning COM/OLE code. (See my Q&amp;A column in VCDJ print and 
            online for extensive info on this sometimes unclear transition of 
            terms and intents.) </P>
            <P style="MARGIN: 0in 0in 0pt">OLECHARs are the standard way to 
            create strings in COM code and by far the most comfortable as long 
            as C and C++ are used in both the client side and the server side. 
            Other languages and tools bring their burden of special constraints 
            that open the way to another kind of string, which constitute the 
            topic of the next paragraph. </P>
            <P align=right style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: right"><B><A 
            href="http://www.devx.com/free/mgznarch/vcdj/1998/dec98/comstring2.asp"><FONT 
            color=#990033>continued...</FONT></A></B></P>
            <DIV align=center>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="mso-cellspacing: 1.5pt">
              <TBODY>
              <TR>
                <TD 
                style="PADDING-BOTTOM: 0.75pt; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; PADDING-TOP: 0.75pt">
                  <P align=center class=MsoNormal 
                  style="TEXT-ALIGN: center"><SPAN 
                  style="FONT-FAMILY: Arial; FONT-SIZE: 9pt">Copyright &copy; 1999 - 
                  Visual C++ Developers Journal<SPAN 
                  style="COLOR: black"><o:p></o:p></SPAN></SPAN></P></TD></TR></TBODY></TABLE></DIV>
            <P class=MsoNormal>&nbsp;<o:p></o:p></P><SPAN 
            style="COLOR: black; FONT-FAMILY: Arial; FONT-SIZE: 9pt; mso-fareast-font-family: SimSun; mso-fareast-language: EN-US; mso-ansi-language: EN-US; mso-bidi-language: AR-SA"><BR 
            clear=all style="PAGE-BREAK-BEFORE: always"></SPAN>
            <P><B><SPAN style="COLOR: #0e3092; FONT-SIZE: 10pt">BSTRs 
            </SPAN></B></P>
            <P>B-strings, more properly called Basic strings, are a special kind 
            of string format. Instead of comprising a classic array of 
            characters followed by a NUL character (code \0) that marks the 
            termination of the array, the structure of the data in memory is a 
            superset of OLECHAR. In short, a BSTR is a null-terminated array of 
            OLECHARs prefixed by its length. The string length is determined by 
            the character count, not by the index of the first null character. 
            </P>
            <P>This presence of the length of the object before the actual array 
            data renders these strings suitable for manipulation in high-level 
            tools like Visual Basic (for which this string format was invented 
            in the first place) and Java on a COM-aware virtual machine like 
            Microsoft's JVM. Actually, there is no other way to exchange 
            string-like data with components written in those languages than to 
            employ BSTRs. While in C and C++ the developer has to understand and 
            use the data type in a rather uncomfortable manner, both Visual 
            Basic and Java encapsulate them into their traditional string types, 
            respectively String and java.lang.String. The final developer is 
            therefore shielded from the subtleties of the organization of the 
            raw bytes in memory. Moreover, the tools take care of allocating and 
            freeing the memory required to contain their content without the 
            programmer needing to know how this process works behind the scenes. 
            </P>
            <P>This is the brilliant side of the medal of course. You as the 
            C/C++ hardcore engineer get the tough part of the work, since you 
            need to learn a completely new specific set of APIs that carry out 
            the basic operations with Basic strings. The family of functions is 
            amazingly named "system strings management API" and its members can 
            easily be distinguished by the "Sys" prefix in their names. </P>
            <P>The following code snippet, borrowed from Oleauto.h (this stuff 
            used to be most useful when coupled with Automation, as Visual 
            Basic's COM support was a lot less powerful then), shows the 
            prototypes of each of the functions in the group: </P>
            <TABLE border=0 cellPadding=0 cellSpacing=3 
            style="WIDTH: 100%; mso-cellspacing: 1.5pt; mso-padding-alt: 3.75pt 3.75pt 3.75pt 3.75pt" 
            width="100%">
              <TBODY>
              <TR>
                <TD 
                style="BACKGROUND: #dfdfdf; PADDING-BOTTOM: 3.75pt; PADDING-LEFT: 3.75pt; PADDING-RIGHT: 3.75pt; PADDING-TOP: 3.75pt"><PRE>/*---------------------------------------------------------------------*/</PRE><PRE>/*<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>BSTR API<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>*/</PRE><PRE>/*---------------------------------------------------------------------*/</PRE><PRE>&nbsp;<o:p></o:p></PRE><PRE>WINOLEAUTAPI_(BSTR) SysAllocString(const OLECHAR *);</PRE><PRE>WINOLEAUTAPI_(INT)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>SysReAllocString(BSTR *, const OLECHAR *);</PRE><PRE>WINOLEAUTAPI_(BSTR) SysAllocStringLen(const OLECHAR *, UINT);</PRE><PRE>WINOLEAUTAPI_(INT)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>SysReAllocStringLen(BSTR *, const OLECHAR *, UINT);</PRE><PRE>WINOLEAUTAPI_(void) SysFreeString(BSTR);</PRE><PRE>WINOLEAUTAPI_(UINT) SysStringLen(BSTR);</PRE><PRE>&nbsp;<o:p></o:p></PRE><PRE>#ifdef _WIN32</PRE><PRE>WINOLEAUTAPI_(UINT) SysStringByteLen(BSTR bstr);</PRE><PRE>WINOLEAUTAPI_(BSTR) SysAllocStringByteLen(LPCSTR psz, UINT len);</PRE><PRE>#endif</PRE></TD></TR></TBODY></TABLE>
            <P>Don't be unnerved by the probably unfamiliar 
            <I>WINOLEAUTAPI_()</I> word preceding all the functions; it is 
            simply a macro defined in the same header file that expands to a 
            long list of modifiers necessary to adjust the calling convention, 
            exportation details, and return type. You can blissfully ignore it 
            for our purposes. </P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -