查看: 563  |  回复: 0
  VB6 VB真是想不到系列之五:高效字串指针类
楼主
发表于 2023年12月17日 00:41

关键字:VB、HCAK、字串指针、BSTR、效率、内存共享

难度:中级或高级

参考文章:

1、2000年7月VBPJ Black Belt专栏文章《Modify a Varialbe's Pointer》

   作者:Bill McCarthy

2、1998年4月VBPJ Black Belt专栏文章《Play VB's Strings》

   作者:Francesco Balena

引言:

    本想以内存共享做为VB指针专题的最后一篇,写着写着发现字串的问题应该单独谈谈。在内存共享的问题上,我尤其关心的是字串的共享,因为在我一个多月前发布的源码里用的是《HardCore VB》里Bruce Mckinney提供的CShareStr类,它实现了字串的内存共享。但是Bruce也没有突破局限,对字串的处理依然是CopyMemory的乾坤大挪移,尤其是还要进行讨厌的ANSI/DBCS和Unicode的转换。我在readme里说过它效率极低,应该采用Variant或Byte数组来实现,才能避免转换。后来又想到可以用StrPtr来做,并在VC里用DLL共享节实现了可以不进行转换的字串内存共享。不过在VC里我仍然需要用SysAllocString来建立VB能使用的BSTR。这都不是我想要的,我想要的东西要象VC里的CString的一样,只要字串够大,对其赋值就不用重新分配内存,还要象VC里CComBSTR类一样可以Attach到一个特定BSTR。

    知道该怎么做,是在看了VBPJ上Bill McCarthy和Francesco Balena的两篇文章之后。Bill用修改SafeArray描述结构实现了数组的内存共享,而Francesco则对字串指针进行深入的探讨。但是Bill和Francesco的东西都没有实现我想要的字串类。

    方法知道了,实现并不难,所以我决定自己来包装一个这样的东西。

正文:

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

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

具体代码只能由VIP查看,请升级

    用法如下,假设我们已通过VitualAlloc,HeapAlloc,MapViewOfFile这样的内存管理API得到了一个4k个字节的可读写的内存地址baseAddr:

具体代码只能由VIP查看,请升级

    我也不在这里讲这个类的详细原理,可以参考我前面说的两篇文章。

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

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

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

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

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

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

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

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

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

后计:

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

    本文和下篇文章的代码,以及用这个类来实现的共享内存的代码,我会发布到CSDN共享软件上,名字是《内存共享和指针》。

您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2024 MaNongKu.com