VB 深度下潛之 海蛇纏繞

來源:互聯網
上載者:User
下潛深度(十米,水溫0°C),時間北京時間零點整。
“海蛇”有人在驚呼。

只見在海底深處遊來一條黑色的長長的海蛇,幾乎所有的人都在發獃。但是海蛇說了一句讓我們膽寒的話“我就是有名的VB字串,如果你們繼續下潛的話,就得想通過我”。

我習慣性的觀察著它,因為我知道要打敗一個對手,就必須深入的瞭解對手。

因此我寫了一段小CODE來瞭解它。

Dim str As String



str = "Give me a 美女"

Dim L1 As Long

Dim L2 As Long

L1 = Len(str)

L2 = LenB(str)

Debug.Print L1, L2

這個代碼運行得很好,完全符合我的想像,在立即視窗中顯示了12,24,

Good,於是我準備在視窗中用TextOut把它列印出來,至於為什麼我一定要這個函數而不用其它的,你管得著嗎?所以我寫下了於下代碼

Dim str As String



str = "Give me a 美女"

Dim L1 As Long

Dim L2 As Long

L1 = Len(str)

L2 = LenB(str)

Debug.Print L1, L2

TextOut Me.hDC, 100, 100, str, L1

結果我發現不對?看來是字串長度不對,想起來了,在VB中字串是BSTR型的,那麼應該用L2作長度,對不對呢,試試就知道了。

天呀,在字串後出現了天書,難道是上帝在暗示我什麼時候給我一個美女?

不過我想上帝沒有這麼快就會答應我,因此一定是My Code有問題。

當我正在沉思的時候,所有的人都在觀注著我。沒辦法,太帥了。

所以我又迅速寫下了以下的代碼

Private Declare Function LenANSI Lib "kernel32" Alias "lstrlenA" (ByVal string1 As String) As Long

……

Dim str As String



str = "Give me a 美女"

Dim TrueLen As Long

TrueLen = LenANSI(str)

TextOut Me.hDC, 100, 100, str, TrueLen

當我快速地按下F5後,天空中便有了迴響,“Give me a 美女”這句話已得到了正確的響應。

這時候我看著這條海蛇,滿有信心地向它遊去,但是它卻很詭秘的一笑。

你見過蛇的笑容麼,它也很緩緩的遊過來了。

“如果你們打算就這樣通過我的話,也想得太容易了”這句話為什麼這麼熟悉呢。是不是在黃金十二宮裡的什麼人說的吧,

“給你們一個小考驗,你們知道vbNullString 和 “” 有什麼區別嗎?”

“別以為你是海蛇就了不起,你這問題也太簡單了吧”我身邊一個長得不是很難看的小夥子,人送外號(天下第七帥),“你以為我沒讀過海洋生物指南呀(物件瀏覽器)

Const vbNullString = ""

VBA.Constants 的成員

當調用一個外部過程,需要一個非零值的字串時,所使用的常數

“那你的意思是說是一樣的了,那麼vbNullChar呢?”海蛇不懷好意地看著天下第七帥。

“那當然是一樣的了,你看VB的說明麼”天下第七帥衝口而出,不過他又覺得好象有些不對。但是VB的物件瀏覽器上的確寫著

Const vbNullChar = ""

VBA.Constants 的成員

那麼下面這段代碼代表什麼呢?

海蛇給出了它的代碼

Dim s1 As String

Dim s2 As String

Dim s3 As String



s1 = vbNullString

s2 = vbNullChar

s3 = ""



Debug.Print StrPtr(s1), StrPtr(s2), StrPtr(s3)

Debug.Print LenB(s1), LenB(s2), LenB(s3)

天下第七帥按下F5後,他很驚訝海蛇代碼的運行結果

0 1899284 1434596

0 2 0

那麼就是說VB的說明和海蛇之間一定有人錯了。而且,對於採用S1兩個值都是零,指標指向零,長度為零,它不是一個普通意義上的零值呀。

天下第七帥於是轉過頭來看著我。

“小子,出風頭吧,來吧,我先給你們看點東西”

“你們想要打敗海蛇,就一定要瞭解海蛇的結構”

VB的字串是一個標準的BSTR字串,比如說”Hello”這個字串它的結構是這樣的

A 0
0
0
‘H’
0
‘e’
0
‘l’
0
‘l’
0
‘o’
0
0
0


可以看到前面四個位元組代表 字串實際長度所佔位元組數,它是一個Long值。

而最後兩個位元組是代表零值的結尾字元。

而中間的十個位元組正好是字串的內容。

如果我們用s1=”Hello”,那麼s1是指向什麼地方呢。

“最初我以為s1是指向第一個位元組,但是當我用自編的VB記憶體觀測工具來看strptr(s1)後面所跟的位元組值時發現,s1是指向第五個位元組,也就是我們字串真正開始的地方。”

“大家都瞭解了海蛇的結構了,那麼它剛才提出的三種情況為什麼會有不同呢?”我向還在發獃的下潛者。

“是呀,為什嗎?”

好了,拿出你們的OleView,在File-> View TypeLib中開啟VB6.DLL,你是不是看到了一個很奇妙的天地,別發獃,找到以下部分

Modules->Modules Constants

開啟他們你便會看到VB內部真正的定義了。

[helpcontext(0x0010aa32)] const LPSTR vbNullString = "";

[helpcontext(0x0010aa32)] const LPSTR vbNullChar = "\0";

看到了沒有,vbNullString指向一個空字串,但這個空字串是零址的。而vbNullChar則是一個零字元(相當於C中字串中最後一個字元)。那麼我們來看海蛇的代碼運行時發生了什麼

s1 = vbNullString

VB看到這句時,它很清楚把S1的值變成了零

s2 = vbNullChar

VB看到這句時,它做了幾個動作,它用SysAllocStringLen在堆中分配了一個BSTR字串,然後將’\0’複製到這個字串裡。

s3 = ""

這裡VB做了很多工作,首先,VB在編譯時間,把””當成了一個常量,它必須為這個Null 字元串內部申請一個變數。當EXE檔案載入後,也得把它設定一個地址,雖然它什麼都不代表

是一個 00 00 00 00 00 00 這樣的字串,它需要6個位元組(四個頭位元組和2個尾位元組)

然後當看到這句時再把第五個位元組的地址值傳給s3

所以,雖然你只是信手寫了一個””,結果VB多作了很多工作。6個位元組雖然不多,但是在一個大工程裡,大家都到處寫“”,那麼也是很可觀的一筆開銷。所以下次你絕對不要再用””,而一定要用vbNullString

“你說,是麼,海蛇”,我輕蔑地看著它。

海蛇看到大家都恍然大悟的樣子,再此發出了它的笑聲(海蛇會笑嗎?)

“瞭解我,並不是真正的掌控我,很多C的潛水員會對VB不屑一顧,你們知道是為什嗎?”

“慢,VB的字串操作太慢了”很多潛水者都回搶著回答這個問題。

“呵呵,是的,”海蛇放聲大笑,慢慢地遊向深海“I will Back!”

留下我們這群潛水的人,大家在思索,我們真正瞭解海蛇了麼,因為VB海洋傳說中海蛇是相當可怕的,它會這麼輕易地走開麼,而且,它所說的 I will Back又是指什嗎?

但是我們會繼續下潛…….

“看,珊瑚礁”有人在驚呼!




相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。