24小时热门版块排行榜    

Znn3bq.jpeg
查看: 140  |  回复: 0
当前主题已经存档。

miRNA

至尊木虫 (职业作家)

水王之王(愚愚学园管理员)

[交流] VB“变态”用法之高效字串指针类

使用VB里的字串类型String有两大不足:第一、它的分配是由VB运行时控制,我们不能将其分配在指定内存处;第二,任何一次对字串的赋值操作都要进行内存重新分配。要实现高效、灵活的字串处理,我们必须克服这两大不足。

  对于第一个问题,通过修改String变量里放着的BSTR描述符指针可以实现;对于第二个问题,可以用Mid语句(注意是语句而不是函数)来赋值。不详细讲了,直接看下面的这个类:
  

  Option Explicit

  '********************************************************
       'clsBSTR.cls

  '作者: 熊超 ID: AdamBear 2

  '********************************************************

  

  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"

  使用这个类有几个需要注意的地方。

  1、读字串时可以用sString属性来读,更快。

  读sShare有两种方法,一种是用缺省属性Data来读,一种是直接用sString属性来读。用sString属性不重新分配内存,要快得多。

  2、不要直接给sString赋值,应使用缺省的data属性来赋值。

  之所以把sString属性暴露出来,是为了效率和方便。我们可以用Mid语句对其进行修改,但不要直接用"="来赋值。

  3、注意Attach的第二个参数,表示字串的最大字节数,不要让它超过已经分配的内存。

  4、用AttachStr将本字串对象Attach到某个字串(比如上面的y)上后,不能再对这个字串y重新赋值,也不能将其传递到会对其重新赋值的过程。

  这么多需要注意的问题,用起来岂不是更不方便。的确,用它的之前要考虑是不是必须的。因为建立这个类也一样有开销。所以还有一个需要注意的问题:

  5、它主要的应用还是在于将字串安放在指定内存处。虽然它也可以让同一个进程内几个的字串达到共享的目的,但是如果只是两三个很小的字串这样时做反而慢了。

  后计:

  数组指针和字串指针我们已经谈过了,对于普通的数值类型变量的指针没有什么Hack的必要,但是它关系到一个有用的技术,下篇文章再谈。

[ Last edited by 幻影无痕 on 2006-10-3 at 14:06 ]
回复此楼

» 猜你喜欢

〖愚愚学园〗http://www.scifans.net免费代理|免费期刊|ezproxy|文献检索|学术资源|免费资源
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 miRNA 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 294求调剂 +9 淡然654321 2026-04-15 9/450 2026-04-16 08:46 by 星空电池
[考研] 297,工科调剂? +10 河南农业大学-能 2026-04-14 10/500 2026-04-15 21:50 by noqvsozv
[考研] 22专硕求调剂 +9 haoyun上岸 2026-04-11 11/550 2026-04-15 14:47 by elainzaizai
[考研] 0854调剂 +13 长弓傲 2026-04-12 16/800 2026-04-15 13:45 by fenglj492
[考研] 一志愿沪9,326求生物学调剂 +10 刘墨墨 2026-04-13 10/500 2026-04-14 15:16 by zs92450
[考研] 食品与营养(0955)271求调剂 +15 升格阿达 2026-04-12 16/800 2026-04-14 13:18 by 浮若_安生
[考研] 求调剂288 +7 ioodiiij 2026-04-10 9/450 2026-04-13 08:33 by Hayaay
[考研] +10 李多米lee. 2026-04-12 11/550 2026-04-12 22:58 by yuyin1233
[考研] 电气专硕320求调剂 +6 小麻子111 2026-04-10 6/300 2026-04-12 10:54 by lemon6009
[考研] 调剂 +5 文道星台 2026-04-11 5/250 2026-04-11 15:01 by 凯凯要变帅
[考研] 087100初试311求调剂 +4 任雅琴 2026-04-09 4/200 2026-04-11 10:33 by zhq0425
[考研] 22408 327分求调剂 +4 韵风kon 2026-04-10 4/200 2026-04-11 09:51 by 猪会飞
[考研] 311求调剂 +13 xyp想读书 2026-04-10 14/700 2026-04-11 09:41 by 猪会飞
[考研] 吉大计算机技术331分,英语六级,求调剂 +3 峰峰021116 2026-04-09 3/150 2026-04-10 20:01 by chemisry
[考研] 计算机类求调剂,22408-274分 +7 上岸de小虫 2026-04-09 8/400 2026-04-10 19:56 by fxue1114
[考研] 一志愿矿大,材料工程专硕314分,0856可调都可以 +15 无懈可击的巨人 2026-04-09 15/750 2026-04-10 18:10 by hmn_wj
[考研] 085800 能源动力求调剂 +6 阿biu啊啊啊啊啊 2026-04-10 6/300 2026-04-10 15:03 by hemengdong
[考研] 一志愿中科院105500专业总分315求调剂 +6 lallalh 2026-04-09 7/350 2026-04-09 17:51 by lallalh
[考研] 332,085601求调剂 +12 ydfyh 2026-04-09 14/700 2026-04-09 17:28 by wp06
[考研] 化学工程与技术专业一志愿哈工程 291分B区 国家级大创负责人 有一作论文 +13 Emmy~ 2026-04-09 13/650 2026-04-09 14:47 by only周
信息提示
请填处理意见