成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

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

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

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

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

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

  1. Function GetCharByte(ByVal OneChar As Integer, 
    ByVal IsHighByte As Boolean) As Byte 
  2. ' 該函數(shù)獲得一個(gè)字符的高字節(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ù)將一個(gè)字符串轉(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)換一個(gè)字符串  
  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. '將每一個(gè)字符串對(duì)應(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ù)組的第一個(gè)元素以傳址的方式傳入動(dòng)態(tài)連接庫(kù),DLL過(guò)程就可以正確地訪問(wèn)數(shù)組中的所有字符串了。但是,使用這種方法,當(dāng)DLL過(guò)程處理結(jié)束返回VB時(shí),VB得到的仍然是字節(jié)數(shù)組。如果需要在VB中再次得到該字節(jié)數(shù)組表示的字符串,還要把整個(gè)字節(jié)數(shù)組重新以0為分割符分成多個(gè)子數(shù)組(每個(gè)子數(shù)組都對(duì)應(yīng)原來(lái)字符串?dāng)?shù)組中的一個(gè)元素),然后使用VB函數(shù)StrConv將每個(gè)子數(shù)組轉(zhuǎn)換成字符串(轉(zhuǎn)換時(shí)第二個(gè)參數(shù)選vbUnicode),就可以顯示或進(jìn)行其它操作了。例如,其中一個(gè)子數(shù)組的名字是SubAry,則函數(shù)StrConv(SubAry,vbUnicode)就返回了它所對(duì)應(yīng)的字符串。

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

【編輯推薦】

  1. VB.NET使用Alias子句簡(jiǎn)介
  2. 詳細(xì)描述VB調(diào)用動(dòng)態(tài)連接庫(kù)
  3. 敘述VB.NET創(chuàng)建控件數(shù)組
  4. 淺析VB.NET繪制GDI圖形的方法
  5. VB.NET Declare語(yǔ)句學(xué)習(xí)筆記
責(zé)任編輯:佚名 來(lái)源: 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-08 15:11:22

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

2009-11-10 12:06:17

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

2010-01-13 15:12:04

VB.NET字符串合并

2009-10-14 15:44:04

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

2009-10-28 17:44:31

VB.NET語(yǔ)言

2010-01-11 13:42:20

VB.NET字符串加密

2009-11-02 14:48:45

VB.NET HOOK

2009-10-15 11:42:05

VB.Net賦值語(yǔ)句

2009-11-10 16:46:52

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

2009-11-02 17:12:01

VB和VB.NET

2009-10-26 14:06:03

2009-10-21 09:10:52

VB.NET壓縮

2009-10-15 17:50:48

VB.NET調(diào)用API
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 夜夜爽99久久国产综合精品女不卡 | 成人午夜在线视频 | 亚洲劲爆av | 国产精品a久久久久 | 亚洲一区 中文字幕 | 国产成人综合在线 | 98成人网 | 天天夜碰日日摸日日澡 | 欧美视频在线播放 | 成人欧美一区二区 | 国产毛片久久久久久久久春天 | 久久久天堂 | 人人九九精 | 99色播 | 一本一道久久a久久精品蜜桃 | 国产96在线 | 国产精品久久片 | 久久久国产一区二区 | 欧美日韩国产中文字幕 | 国产精品日韩在线 | 91在线视频网址 | 国产一区二区激情视频 | 免费精品视频一区 | 91精品观看| 超碰精品在线 | 中文字幕一区二区三区日韩精品 | 日韩网站免费观看 | 91在线网站 | 久久久www成人免费精品张筱雨 | 欧美一级淫片007 | 成人不卡在线 | 香蕉视频一区二区 | 狠狠干狠狠操 | 成人在线免费看 | 日本黄色影片在线观看 | 亚洲三区在线观看 | 精品在线一区二区三区 | 狠狠操电影| 亚洲狠狠| 91久久久久久 | 亚洲精品乱码久久久久久久久 |