Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
注释:不要直接对sString赋值(可以用MID语句),将其设为公有仅为提高效率。
Public sString As String 注释:BSTR描述符指针
Private pStr As Long 注释:BSTR地址
Private nMaxLen As Long 注释:BSTR最大字节数
注释:让本字串指向特定地址
Public Sub Attach(Addr As Long, Optional nLen As Long)
pStr = Addr
注释:修改BSTR描述符指针,使其指向Addr
CopyMemory ByVal VarPtr(sString), Addr, 4
If IsMissing(nLen) Then Exit Sub
注释:设定最大字串字节数
nMaxLen = nLen
End Sub
注释:还原本字串原BSTR描述符
Public Sub Detach()
CopyMemory ByVal VarPtr(sString), 0&, 4
End Sub
注释:让本字串指向源字串
Public Sub AttachStr(sStr As String)
Attach StrPtr(sStr), LenB(sStr)
End Sub
注释:data为缺省属性
Public Property Let data(sVal As String)
Dim c As Long
c = LenB(sVal)
注释:超过最大字串数,抛出错误。
If c > nMaxLen Then Err.Raise vbObjectError + 3000, _
"CString::Let Data", "溢出"
注释:写字串长度
CopyMemory ByVal (pStr - 4), c, 4
注释:写字串
Mid(sString, 1) = sVal
End Property
注释:可以通过公有变量sString来读字串,效率更高
Public Property Get data() As String
data = sString
End Property
Private Sub Class_Terminate()
Call Detach
End Sub
用法如下,假设我们已通过VitualAlloc,HeapAlloc,MapViewOfFile这样的内存管理API得到了一个4k个字节的可读写的内存地址baseAddr:
Dim sShare As New clsBSTR
注释:留下前4个字节用于BSTR保存字串字节数
sShare.Attach(baseAddr+4, 4096-4)
注释:下面的字串"Test"会直接写到baseAddr+4字节处
sShare = "Test"
Dim y As String
注释:读字串时可以用sString属性或缺省属性
y = sShare.sString
注释:用AttachStr方法Attach到一个字串。
注释:必须要先Detach
sShare.Detach
sShare.AttachStr(y)
sShare = "Hahaha"
Debug.Print y
注释:一旦AttachStr到字串y后,对sShare的修改就相当于对y的修改。
注释:并且以后对y的修改也只能用Mid语句
Mid(y, 1) = "xxxxx"
注释:不能直接赋值,这样VB会将原来y所指(也是sShare所指)内存释放,
注释: 重新分配y。这样在访问sShare时会出错。
注释:y = "Test"