自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

VB.NET字符串?dāng)?shù)組全面分析

開發(fā) 后端
這里介紹當(dāng)需要把一個VB.NET字符串?dāng)?shù)組整個傳入動態(tài)連接庫時,情況就變得復(fù)雜多了,用傳遞簡單數(shù)據(jù)類型數(shù)組的方式來傳遞VB.NET字符串?dāng)?shù)組是行不通的。

VB.NET有很多值得學(xué)習(xí)的地方,這里我們主要介紹VB.NET字符串?dāng)?shù)組,包括介紹將VB.NET字符串?dāng)?shù)組轉(zhuǎn)換成字節(jié)數(shù)組等方面。

大部分的DLL過程(包括Windows 95 API中的所有過程)使用LPSTR類型字符串,這是指向標(biāo)準(zhǔn)的以null結(jié)束的C語言字符串的指針,它也被稱為ASCIIZ字符串。LPSTR 沒有前綴。下圖顯示了一個指向ASCIIZ字符串的LPSTR。

如果DLL過程需要一個LPSTR(指向以null結(jié)束的字符串的指針)作為參數(shù),可以在 VB 中將一個字符串以傳值的方式傳遞給它。因為指向BSTR的指針實際指向以null值結(jié)束的字符串的第一個數(shù)據(jù)字節(jié),所以對于DLL過程來說,它就是一個 LPSTR。這樣傳入動態(tài)連接庫的字符串,DLL過程也可以對它進(jìn)行修改,盡管它是以傳值方式傳入的。只有當(dāng)DLL過程需要一個指向LPSTR的指針時,才以傳址的方式傳入字符串,這時DLL過程得到的是一個指向字符串指針的指針(相當(dāng)于C/C++中的char**),而不是通常所用的字符串的首地址(相當(dāng)于C/C++中的char*)。

當(dāng)需要把一個VB.NET字符串?dāng)?shù)組整個傳入動態(tài)連接庫時,情況就變得復(fù)雜多了,用傳遞簡單數(shù)據(jù)類型數(shù)組的方式來傳遞VB.NET字符串?dāng)?shù)組是行不通的。當(dāng)我們以傳值的方式將一個VB.NET字符串?dāng)?shù)組的第一個元素傳進(jìn)動態(tài)連接庫時,DLL過程得到的實際上是該元素壓入堆棧段后的地址,而不是數(shù)據(jù)段中整個數(shù)組的首地址。也就是說,這時DLL過程只能得到數(shù)組的第一個元素,而無法訪問整個數(shù)組。而以傳址方式傳入第一個元素時,DLL過程只能得到指向該元素在堆棧段中地址的指針,同樣無法訪問整個數(shù)組。這不能不說是VB的一個不足。因此,在程序設(shè)計中,如果確實需要將整個VB.NET字符串?dāng)?shù)組傳入動態(tài)庫,就必須采取其它方法。

我們知道,在VB中,有一種Byte數(shù)據(jù)類型。每個Byte型變量占一個字節(jié),不含符號位,因 此所能表示的范圍為0到255。這種數(shù)據(jù)類型是專門用于存放二進(jìn)制數(shù)據(jù)的。為了將整個VB.NET字符串?dāng)?shù)組傳進(jìn)動態(tài)庫,可以用字節(jié)數(shù)組來保存字符串。由于Byte是一種簡單數(shù)據(jù)類型,因此字節(jié)數(shù)組的傳遞是非常簡單的。首先,需要把一個字符串正確地轉(zhuǎn)變成一個字節(jié)數(shù)組。這要涉及一 些字符集的知識。Windows 95和VB使用不同的字符集,Windows 95 API使用的是ANSI或DBCS 字符集,而VB使用的則是Unicode字符集。所謂ANSI字符集,是指每個字符都用一個字節(jié)表示,因此最多只能有28=256個不同的字符,這對于英語來說已經(jīng)足夠了,但不能完全支持其它語言。DBCS字符集支持很多不同的東亞語言,如漢語、日語和朝鮮語,它使用數(shù)字0-255表示ASCII 字符,其它大于255或小于0的數(shù)字表明該字符屬于非拉丁字符集;在DBCS中,ASCII字符的長度是一個字節(jié),而漢語、日語和其它東亞字符的長度是2個字節(jié)。而Unicode字符集則完全用兩個字節(jié)表示一個字符,因此最多可以表示216=65536個不同字符。也就是說,ANSI字符集中所有的字符都只占一個字節(jié),DBCS字符集中ASCII字符占一個字節(jié),漢字占兩個字節(jié),Unicode 字符集中每個字符都占兩個字節(jié)。由于VB與WindowsAPI使用的字符集不同,因此在進(jìn)行字符串到字節(jié)數(shù)組的轉(zhuǎn)換時,當(dāng)用Asc函數(shù)取得一個字符的字節(jié)碼后,需要判斷它是否是一個ASCII 字符;如果是ASCII字符,則在轉(zhuǎn)換后的字節(jié)數(shù)組中就只占一個字節(jié),否則要占兩個字節(jié)。

下面給出了轉(zhuǎn)換函數(shù):GetChar Byte得到一個字符的高字節(jié)或低字節(jié),它的第一個參數(shù)是一個字符的ASCII碼,第二個參數(shù)是標(biāo)志取高字節(jié)還是低字節(jié);StrToByte按DBCS或ANSI格式將一個字符串轉(zhuǎn)換成一個字節(jié)數(shù)組,第一個參數(shù)是待轉(zhuǎn)換的字符串,第二個參數(shù)是轉(zhuǎn)換后的一個定長字節(jié)數(shù)組,若該數(shù)組長度不足以存放整個字符串,則截去超長的部分;ChangeStrAryToByte 利用前兩個函數(shù)將VB.NET字符串?dāng)?shù)組轉(zhuǎn)換成字節(jié)數(shù)組,第一個參數(shù)是定長的VB.NET字符串?dāng)?shù)組,其中每個元素都是一個字符串(各個元素包含的字符數(shù)可以不同),第二個參數(shù)是一個變長的字節(jié)數(shù)組, 保存轉(zhuǎn)換后的結(jié)果。

  1. Function GetCharByte(ByVal OneChar As Integer, 
    ByVal IsHighByte As Boolean) As Byte 
  2. ' 該函數(shù)獲得一個字符的高字節(jié)或低字節(jié)  
  3. If IsHighByte Then  
  4. If OneChar >= 0 Then  
  5. GetCharByte = CByte(OneChar \ 256)  
  6. '右移8位,得到高字節(jié)  
  7. Else  
  8. GetCharByte = CByte((OneChar  
  9. And &H7FFF) \ 256) Or &H80  
  10. End If  
  11. Exit Function  
  12. Else  
  13. GetCharByte = CByte(OneChar And &HFF)  
  14. '屏蔽掉高字節(jié),得到低字節(jié)  
  15. Exit Function  
  16. End If  
  17. End Function  
  18. Sub StrToByte(StrToChange As String, ByteArray() As Byte)  
  19. '該函數(shù)將一個字符串轉(zhuǎn)換成字節(jié)數(shù)組  
  20. Dim LowBound, UpBound As Integer  
  21. Dim i, count, length As Integer  
  22. Dim OneChar As Integer  
  23. count = 0 
  24. length = Len(StrToChange)  
  25. LowBound = LBound(ByteArray)  
  26. UpBound = UBound(ByteArray)  
  27. For i = LowBound To UpBound  
  28. ByteArray(i) = 0 '初始化字節(jié)數(shù)組  
  29. Next  
  30. For i = LowBound To UpBound  
  31. countcount = count + 1  
  32. If count <= length Then  
  33. OneChar = Asc(Mid(StrToChange, count, 1))  
  34. If (OneChar > 255) Or (OneChar < 0) Then  
  35. '該字符是非ASCII字符  
  36. ByteArray(i) = GetCharByte(OneChar, True) '得到高字節(jié)  
  37. ii = i + 1  
  38. If i <= UpBound Then ByteArray(i)  
  39. = GetCharByte(OneChar, False)  
  40. '得到低字節(jié)  
  41. Else  
  42. '該字符是ASCII字符  
  43. ByteArray(i) = OneCha  
  44. End If  
  45. Else  
  46. Exit For  
  47. End If  
  48. Next  
  49. End Sub  
  50.  
  51. Sub ChangeStrAryToByte(StrAry()  
  52. As String, ByteAry() As Byte)  
  53. '將字符串?dāng)?shù)組轉(zhuǎn)換成字節(jié)數(shù)組  
  54. Dim LowBound, UpBound As Integer  
  55. Dim i, count, StartPos, MaxLen As Integer  
  56. Dim TmpByte() As Byte  
  57. LowBound = LBound(StrAry)  
  58. UpBound = UBound(StrAry)  
  59. count = 0 
  60. ReDim ByteAry(0)  
  61. For i = LowBound To UpBound  
  62. MaxLen = LenB(StrAry(i))  
  63. ReDim TmpByte(MaxLen + 1)  
  64. ReDim Preserve ByteAry(count + MaxLen + 1)  
  65. Call StrToByte(StrAry(i), TmpByte) '轉(zhuǎn)換一個字符串  
  66. StartPos = count 
  67. Do  
  68. ByteAry(count) = TmpByte(count - StartPos)  
  69. countcount = count + 1  
  70. If ByteAry(count - 1) = 0 Then Exit Do Loop   
  71. '將每一個字符串對應(yīng)的字節(jié)數(shù)組按順序填入結(jié)果數(shù)組中  
  72. ReDim Preserve ByteAry(count - 1)  
  73. Next i  
  74. End Sub 

這樣,VB.NET字符串?dāng)?shù)組就全部轉(zhuǎn)換成了字節(jié)數(shù)組,然后只要將字節(jié)數(shù)組的第一個元素以傳址的方式傳入動態(tài)連接庫,DLL過程就可以正確地訪問數(shù)組中的所有字符串了。但是,使用這種方法,當(dāng)DLL過程處理結(jié)束返回VB時,VB得到的仍然是字節(jié)數(shù)組。如果需要在VB中再次得到該字節(jié)數(shù)組表示的字符串,還要把整個字節(jié)數(shù)組重新以0為分割符分成多個子數(shù)組(每個子數(shù)組都對應(yīng)原來字符串?dāng)?shù)組中的一個元素),然后使用VB函數(shù)StrConv將每個子數(shù)組轉(zhuǎn)換成字符串(轉(zhuǎn)換時第二個參數(shù)選vbUnicode),就可以顯示或進(jìn)行其它操作了。例如,其中一個子數(shù)組的名字是SubAry,則函數(shù)StrConv(SubAry,vbUnicode)就返回了它所對應(yīng)的字符串。

總之,VB應(yīng)用程序和動態(tài)庫間字符串參數(shù)的傳遞是一個比較復(fù)雜的過程,使用時要非常謹(jǐn)慎。同時應(yīng)盡可能避免傳遞字符串?dāng)?shù)組類型的參數(shù),因為這很容易引起下標(biāo)越界、堆棧溢出等嚴(yán)重錯誤。

【編輯推薦】

  1. VB.NET使用Alias子句簡介
  2. 詳細(xì)描述VB調(diào)用動態(tài)連接庫
  3. 敘述VB.NET創(chuàng)建控件數(shù)組
  4. 淺析VB.NET繪制GDI圖形的方法
  5. VB.NET Declare語句學(xué)習(xí)筆記
責(zé)任編輯:佚名 來源: weaseek
相關(guān)推薦

2009-10-27 09:45:03

VB.NET數(shù)組

2009-10-28 10:04:53

VB.NET XmlW

2009-11-04 10:54:53

VB.NET MOVE

2009-10-15 10:57:16

VB.NET Text

2009-10-29 15:16:02

VB.NET文件傳送

2009-10-14 15:20:21

VB.NET窗體指針

2009-11-02 15:57:36

VB.NET WEB

2010-01-13 15:12:04

VB.NET字符串合并

2009-11-10 12:06:17

VB.NET字符串函數(shù)

2010-01-08 15:11:22

VB.NET字符串轉(zhuǎn)義

2009-10-14 15:44:04

VB.NET字節(jié)數(shù)組

2009-10-28 17:44:31

VB.NET語言

2010-01-11 13:42:20

VB.NET字符串加密

2009-11-02 14:48:45

VB.NET HOOK

2009-11-10 16:46:52

VB.NET指針應(yīng)用

2009-10-15 11:42:05

VB.Net賦值語句

2009-11-02 17:12:01

VB和VB.NET

2009-10-21 09:10:52

VB.NET壓縮

2009-10-15 17:50:48

VB.NET調(diào)用API

2009-10-20 17:38:20

VB.NET exce
點贊
收藏

51CTO技術(shù)棧公眾號