马大哈 发表于 2009-2-25 01:20:37

【原创】VB中BSTR字符串的结构

VB里面使用的字符串String就是COM规范中的BSTR,其特点是缓冲区前面有4字节的前缀用于说明缓冲区的长度:

http://www.m5home.com/bbs/data/attachment/forum/dvbbs/2009-2/2009225185971226.gif

因此这种结构可以保证能包含任意的内容,包括LPSTR中用于标志字符串结束的NULL.
VB在向API中以ByVal方式传递String时,实际上是把缓冲区的地址传了进去,因此API可以通过这个缓冲区来修改字符串内容.

以下这个代码可以直观的展示上面的说明:



Option Explicit
'说明BSTR结构的测试代码
'BY 嗷嗷叫的老马
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
   ByVal Destination As Long, _
   ByVal Source As Long, _
   ByVal Length As Long)
Sub Main()
    Dim I As String, J As Long, K As Long
   
    I = "12345"
    Call CopyMemory(VarPtr(J), StrPtr(I) - 4, 4)      '-4,指针就指向了I的前缀
    MsgBox "字符串A" & Chr(0) & "字符串B"
            'MsgBox也是以NULL为字符串结尾的,因此无法显示出字符串B.
    MsgBox "缓冲区地址 = &H" & Hex(StrPtr(I)) & vbCrLf & vbCrLf & _
            "LenB(BSTR) = " & LenB(I) & vbCrLf & vbCrLf & _
            "CopyMemory得到的长度 = " & J
End Sub

阿杰 发表于 2009-2-25 11:05:53

不错,经典实用

马大哈 发表于 2009-2-26 14:50:33

<p>LPSTR就等于没有长度前缀的BSTR,请看后面蓝色部分.</p>
<p>&nbsp;</p>
<p>由于没有长度标识,因此LPSTR以NULL为字符串结束标志,所以LPSTR无法正常存放一个包含了NULL的字符串.</p>

马大哈 发表于 2009-3-1 03:15:45

<p>关于问题一:</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 这个我不太清楚,C我不熟.不过貌似C里就LPSTR使用得多.....</p>
<p>&nbsp;</p>
<p>问题二:</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 不是"没什么作用",而是根本没得用......VB里面就只有BSTR类型的字符串可用........</p>
<p>&nbsp;</p>
<p>问题三:</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 我好象没见到哪个API只需要传缓冲区进去而不需要指定长度的....?想了半天真没想出来.</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 不过呢,关于字符串返回的API的工作方式,我可以大约地说明一下.</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 你看看这个帖子:</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; <font face="Verdana"><a href="dispbbs.asp?boardid=27&amp;id=2373&amp;star=1&amp;page=1">http://www.m5home.com/bbs/viewthread.php?tid=2373&extra=&page=1</a></font></p>
页: [1]
查看完整版本: 【原创】VB中BSTR字符串的结构