bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

vb.net支持any嗎 vb和net

在vb.net中,用什么類型代替vb6.0中的any類型啊?我用object代替時,總是顯示"只不

請參考:

在上蔡等地區,都構建了全面的區域性戰略布局,加強發展的系統性、市場前瞻性、產品創新能力,以專注、極致的服務理念,為客戶提供做網站、網站設計 網站設計制作按需求定制開發,公司網站建設,企業網站建設,成都品牌網站建設,營銷型網站,外貿營銷網站建設,上蔡網站建設費用合理。

當我把一些舊的VB6項目轉變成VS2008時會出現, “Declare”語句中不支持“As Any”的錯誤說明, 例如在National Instrument中有一個VBib-32.vb中有大量的這樣一類的語句:

Declare Function ibcmda32 Lib "Gpib-32.dll" Alias "ibcmda" (ByVal ud AsInteger, ByRef sstr As Any, ByVal cnt As Integer) As Integer

如何辦?

有兩種辦法:

一, 使用具體的參數

例如字符串, 就用string, 那么上面的ByRef as Any, 就寫成ByRef as string, 或者

二, 使用特殊說明MarshalAsAttribute

System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.AsAny)

把這段語句放在相應之處, 然后把Any改成Object, 于是最上面的說明語句寫成

Declare Function ibcmda32 Lib "Gpib-32.dll" Alias "ibcmda" (ByVal ud AsInteger, System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.AsAny) ByRef sstr As Object, ByVal cnt As Integer) As Integer

對于ByVal也是一樣

Public Declare Function GetPrivateProfileString Lib "kernel32" Alias"GetPrivateProfileStringA" (ByVal lpApplicationName As String, System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.AsAny) ByVal lpKeyName As Object, ByVal lpDefault As String,ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName AsString) As Integer

MSDN官方說明, 可以簡寫成:

Declare Sub SetData Lib "..\LIB\UnmgdLib.dll" ( ByVal x As Short, MarshalAsAttribute(UnmanagedType.AsAny)ByVal o As Object)

這種方法本人實際使用, 可行.

怎么利用VB.NET實現三維繪圖

數學上不是有斜二測畫法,算好坐標即可畫出

或者用AnyCAD的.Net圖形控件

也可以調用matlab 實現

vb和vb.net的區別和特點

1、vb.net ?完全符合面向對象的編程語言抽象、封裝、繼承的四大特性,而vb不支持繼承。

2、錯誤處理不同。

vb中只是On Error.....goto和On Errer Resume Next ,這些錯誤稱為非結構化異常處理。而在vb.net中采用的結構化異常處理機制,try...catch....finally控制。

3、兩者產生的窗體不同。

vb.net 允許創建不同類型的應用程序,例如,創建ASP.NET和ASP.NET Web 服務應用程序,還允許創建控制臺應用程序和作為桌面服務運行的應用程序。但是vb 只能創建Windows窗體。

4、數據庫訪問的差別。

vb6.0是通過ADO(Active X Data Objext)來實現對數據庫訪問。而vb.net 是通過ADO.NET來訪問數據庫。

擴展資料

Visual Basic(簡稱VB)是Microsoft公司開發的一種通用的基于對象的程序設計語言,為結構化的、模塊化的、面向對象的、包含協助開發環境的事件驅動為機制的可視化程序設計語言。是一種可用于微軟自家產品開發的語言。

“Visual” 指的是開發圖形用戶界面 (GUI) 的方法——不需編寫大量代碼去描述界面元素的外觀和位置,而只要把預先建立的對象add到屏幕上的一點即可。

“Basic”指的是 BASIC (Beginners All-Purpose Symbolic Instruction Code) 語言,是一種在計算技術發展歷史上應用得最為廣泛的語言。

Visual Basic源自于BASIC編程語言。VB擁有圖形用戶界面(GUI)和快速應用程序開發(RAD)系統,可以輕易的使用DAO、RDO、ADO連接數據庫,或者輕松的創建Active?X控件,用于高效生成類型安全和面向對象的應用程序 。

參考資料:百度百科-Visual Basic

有關于VB對內存讀寫的操作,那位幫幫忙

暈,眼都花了~~給你篇文章看看把,VB用指針操作內存,就倆API

真沒想到VB也可以這樣用之指針技術

想當年東方不敗,黑木崖密室一戰,僅憑一根繡花針獨戰四大高手,神出鬼沒,堪稱天下武林第一高手。若想成為VB里的東方不敗,熟習VB《葵花寶典》,掌握VB指針技術,乃是不二的法門。

欲練神功,引刀……,其實掌握VB指針技術,并不需要那么痛苦。因為說穿了,也就那么幾招,再勤加練習,終可至神出鬼沒之境。廢話少說,讓我們先從指針的定義說起。

一、指針是什么?

不需要去找什么標準的定義,它就是一個32位整數,在C語言和在VB里都可以用Long類型來表示。在32位Windows平臺下它和普通的32位長整型數沒有什么不同,只不過它的值是一個內存地址,正是因為這個整數象針一樣指向一個內存地址,所以就有了指針的概念。

有統計表明,很大一部分程序缺陷和內存的錯誤訪問有關。正是因為指針直接和內存打交道,所以指針一直以來被看成一個危險的東西。以至于不少語言,如著名的JAVA,都不提供對指針操作的支持,所有的內存訪問方面的處理都由編譯器來完成。而象C和C++,指針的使用則是基本功,指針給了程序員極大的自由去隨心所欲地處理內存訪問,很多非常巧妙的東西都要依靠指針技術來完成。

關于一門高級的程序設計語言是不是應該取消指針操作,關于沒有指針操作算不算一門語言的優點,我在這里不討論,因為互聯網上關于這方面的沒有結果的討論,已經造成了占用幾個GB的資源。無論最終你是不是要下定決心修習指針技術《葵花寶典》,了解這門功夫總是有益處的。

注意:在VB里,官方是不鼓勵使用什么指針的,本文所講的任何東西你都別指望取得官方的技術支持,一切都要靠我們自己的努力,一切都更刺激!

讓我們開始神奇的VB指針探險吧!

二、來看看指針能做什么?有什么用?

先來看兩個程序,程序的功能都是交換兩個字串:

【程序一】:

'標準的做法SwapStr

Sub SwapStr(sA As String, sB As String)

Dim sTmp As String

sTmp = sA: sA = sB: sB = sTmp

End Sub

【程序二】:

'用指針的做法SwapPtr

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long)

Sub SwapPtr(sA As String, sB As String)

Dim lTmp As Long

CopyMemory lTmp, ByVal VarPtr(sA), 4

CopyMemory ByVal VarPtr(sA), ByVal VarPtr(sB), 4

CopyMemory ByVal VarPtr(sB), lTmp, 4

End Sub

你是不是以為第一個程序要快,因為它看著簡單而且不用調用API(調用API需要額外的處理,VB文檔明確指出大量調用API將降低程序性能)。但事實上,在VB集成環境中運行,程序二要比程序一快四分之一;而編譯成本機代碼或p-code,程序二基本上要比程序一快一倍。下面是兩個函數在編譯成本機代碼后,運行不同次數所花時間的比較:

運行100000次,SwapStr需要170毫秒,SwapPtr需要90毫秒。

運行200000次,SwapStr需要340毫秒,SwapPtr需要170毫秒。

運行2000000次,SwapStr需要3300毫秒,SwapPtr需要1500毫秒。

的確,調用API是需要額外指令來處理,但是由于使用了指針技術,它沒有進行臨時字串的分配和拷貝,因此速度提高了不少。

怎么樣,想不到吧!C/C++程序員那么依賴指針,無非也是因為使用指針往往能更直接的去處理問題的根源,更有駕馭一切的快感。他們不是不知道使用指針的危險,他們不是不愿意開衛星定位無級變速的汽車,只是騎摩托更有快感,而有些地方只有摩托才走得過去。

和在C里類似,在VB里我們使用指針也不過三個理由:

一是效率,這是一種態度一種追求,在VB里也一樣;

二是不能不用,因為操作系統是C寫的,它時刻都在提醒我們它需要指針;

三是突破限制,VB想照料我們的一切,VB給了我們很強的類型檢查,VB象我們老媽一樣,對我們關心到有時我們會受不了,想偶爾不聽媽媽的話嗎?你需要指針!

但由于缺少官方的技術支持,在VB里,指針變得很神秘。因此在C里一些基本的技術,在VB里就變得比較困難。本文的目的就是要提供給大家一種簡單的方法,來將C處理指針的技術拿到VB里來,并告訴你什么是可行的,什么可行但必須要小心的,什么是可能但不可行的,什么是根本就不可能的。

三、 程咬金的三板斧

是的,程序二基本上就已經讓我們看到VB指針技術的模樣了。總結一下,在VB里用指針技術我們需要掌握三樣東西:CopyMemory,VarPtr/StrPtr/ObjPtr, AdressOf. 三把斧頭,程咬金的三板斧,在VB里Hack的工具。

1、CopyMemory

關于CopyMemory和Bruce McKinney大師的傳奇,MSDN的Knowledge Base中就有文章介紹,你可以搜索"ID: Q129947"的文章。正是這位大師給32位的VB帶來了這個可以移動內存的API,也正是有了這個API,我們才能利用指針完成我們原來想都不敢想的一些工作,感謝Bruce McKinney為我們帶來了VB的指針革命。

如CopyMemory的聲明,它是定義在Kernel32.dll中的RtlMoveMemory這個API,32位C函數庫中的memcpy就是這個API的包裝,如MSDN文檔中所言,它的功能是將從Source指針所指處開始的長度為Length的內存拷貝到Destination所指的內存處。它不會管我們的程序有沒有讀寫該內存所應有的權限,一但它想讀寫被系統所保護的內存時,我們就會得到著名的Access Violation Fault(內存越權訪問錯誤),甚至會引起更著名的general protection (GP) fault(通用保護錯誤) 。所以,在進行本系列文章里的實驗時,請注意隨時保存你的程序文件,在VB集成環境中將"工具"-"選項"中的"環境"選項卡里的"啟動程序時"設為"保存改變",并記住在"立即"窗口中執行危險代碼之前一定要保存我們的工作成果。

2、VatPtr/StrPtr/ObjPtr

它們是VB提供給我們的好寶貝,它們是VBA函數庫中的隱藏函數。為什么要隱藏?因為VB開發小組,不鼓勵我們用指針嘛。

實際上這三個函數在VB運行時庫MSVBVM60.DLL(或MSVBVM50.DLL)中是同一個函數VarPtr(可參見我在本系列第一篇文章里介紹的方法)。

其庫型庫定義如下:

[entry("VarPtr"), hidden]

long _stdcall VarPtr([in] void* Ptr);

[entry("VarPtr"), hidden]

long _stdcall StrPtr([in] BSTR Ptr);

[entry("VarPtr"), hidden]

long _stdcall ObjPtr([in] IUnknown* Ptr);

即然它們是VB運行時庫中的同一個函數,我們也可以在VB里用API方式重新聲明這幾個函數,如下:

Private Declare Function ObjPtr Lib "MSVBVM60" Alias "VarPtr" (var As Object) As Long

Private Declare Function VarPtr Lib "MSVBVM60" (var As Any) As Long

(沒有StrPtr,是因為VB對字符串處理方式有點不同,這方面的問題太多,我將在另一篇文章中詳談。順便提一下,聽說VB.NET里沒有這幾個函數,但只要還能調用API,我們就可以試試上面的幾個聲明,這樣在VB.NET里我們一樣可以進行指針操作。但是請注意,如果通過API調用來使用VarPtr,整個程序二SwapPtr將比原來使用內置VarPtr函數時慢6倍。)

如果你喜歡刨根問底,那么下面就是VarPtr函數在C和匯編語言里的樣子:

在C里樣子是這樣的:

long VarPtr(void* pv){

return (long)pv;

}

所對就的匯編代碼就兩行:

mov eax,dword ptr [esp+4]

ret 4 '彈出棧里參數的值并返回。

之所以讓大家了解VarPtr的具體實現,是想告訴大家它的開銷并不大,因為它們不過兩條指令,即使加上參數賦值、壓棧和調用指令,整個獲取指針的過程也就六條指令。當然,同樣的功能在C語言里,由于語言的直接支持,僅需要一條指令即可。但在VB里,它已經算是最快的函數了,所以我們完全不用擔心使用VarPtr會讓我們失去效率!速度是使用指針技術的根本要求。

一句話,VarPtr返回的是變量所在處的內存地址,也可以說返回了指向變量內存位置的指針,它是我們在VB里處理指針最重要的武器之一。

3、ByVal和ByRef

ByVal傳遞的參數值,而ByRef傳遞的參數的地址。在這里,我們不用去區別傳指針/傳地址/傳引用的不同,在VB里,它們根本就是一個東西的三種不同說法,即使VB的文檔里也有地方在混用這些術語(但在C++里的確要區分指針和引用)

初次接觸上面的程序二SwapPtr的朋友,一定要搞清在里面的CopyMemory調用中,在什么地方要加ByVal,什么地方不加(不加ByVal就是使用VB缺省的ByRef),準確的理解傳值和傳地址(指針)的區別,是在VB里正確使用指針的基礎。

現在一個最簡單的實驗來看這個問題,如下面的程序三:

【程序三】:

'體會ByVal和ByRef

Sub TestCopyMemory()

Dim k As Long

k = 5

Note: CopyMemory ByVal VarPtr(k), 40000, 4

Debug.Print k

End Sub

上面標號Note處的語句的目的,是將k賦值為40000,等同于語句k=40000,你可以在"立即"窗口試驗一下,會發現k的值的確成了40000。

實際上上面這個語句,翻譯成白話,就是從保存常數40000的臨時變量處拷貝4個字節到變量k所在的內存中。

現在我們來改變一個Note處的語句,若改成下面的語句:

Note2: CopyMemory ByVal VarPtr(k), ByVal 40000, 4

這句話的意思就成了,從地址40000拷貝4個字節到變量k所在的內存中。由于地址40000所在的內存我們無權訪問,操作系統會給我們一個Access Violation內存越權訪問錯誤,告訴我們"試圖讀取位置0x00009c40處內存時出錯,該內存不能為'Read'"。

我們再改成如下的語句看看。

Note3: CopyMemory VarPtr(k), 40000, 4

這句話的意思就成了,從保存常數40000的臨時變量處拷貝4個字節到到保存變量k所在內存地址值的臨時變量處。這不會出出內存越權訪問錯誤,但k的值并沒有變。

我們可以把程序改改以更清楚的休現這種區別,如下面的程序四:

【程序四】:

'看看我們的東西被拷貝到哪兒去了

Sub TestCopyMemory()

Dim i As Long, k As Long

k = 5

i = VarPtr(k)

NOTE4: CopyMemory i, 40000, 4

Debug.Print k

Debug.Print i

i = VarPtr(k)

NOTE5: CopyMemory ByVal i, 40000, 4

Debug.Print k

End Sub

程序輸出:

5

40000

40000

由于NOTE4處使用缺省的ByVal,傳遞的是i的地址(也就是指向i的指針),所以常量40000拷貝到了變量i里,因此i的值成了40000,而k的值卻沒有變化。但是,在NOTE4前有:i=VarPtr(k),本意是要把i本身做為一個指針來使用。這時,我們必須如NOTE5那樣用ByVal來傳遞指針i,由于i是指向變量k的指針,所以最后常量40000被拷貝了變量k里。

希望你已經理解了這種區別,在后面問題的討論中,我還會再談到它。

4、AddressOf

它用來得到一個指向VB函數入口地址的指針,不過這個指針只能傳遞給API使用,以使得API能回調VB函數。

本文不準備詳細討論函數指針,關于它的使用請參考VB文檔。

5、拿來主義

實際上,有了CopyMemory,VarPtr,AddressOf這三把斧頭,我們已經可以將C里基本的指針操作拿過來了。

如下面的C程序包括了大部分基本的指針指針操作:

struct POINT{

int x; int y;

};

int Compare(void* elem1, void* elem2){}

void PtrDemo(){

//指針聲明:

char c = 'X'; //聲明一個char型變量

char* pc; long* pl; //聲明普通指針

POINT* pPt; //聲明結構指針

void* pv; //聲明無類型指針

int (*pfnCastToInt)(void *, void*);//聲明函數指針:

//指針賦值:

pc = c; //將變量c的地址值賦給指針pc

pfnCompare = Compare; //函數指針賦值。

//指針取值:

c = *pc; //將指針pc所指處的內存值賦給變量c

//用指針賦值:

*pc = 'Y' //將'Y'賦給指針pc所指內存變量里。

//指針移動:

pc++; pl--;

}

這些對指針操作在VB里都有等同的東西,前面討論ByVal和ByRef時曾說過傳指針和傳地址是一回事,實際上當我們在VB里用缺省的ByRef聲明函數參數時,我們已經就聲明了指針。

如一個C聲明的函數:long Func(char* pc)

其對應的VB聲明是:Function Func(pc As Byte) As Long

這時參數pc使用缺省的ByRef傳地址方式來傳遞,這和C里用指針來傳遞參數是一樣。

那么怎么才能象C里那樣明確地聲明一個指針呢?

很簡單,如前所說,用一個32位長整數來表達指針就行。在VB里就是用Long型來明確地聲明指針,我們不用區分是普通指針、無類型指針還是函數指針,通通都可用Long來聲明。而給一個指針賦值,就是賦給它用VarPar得到的另一個變量的地址。具體見程序五。

【程序五】:同C一樣,各種指針。

Type POINT

X As Integer

Y As Integer

End Type

Public Function Compare(elem1 As Long, elem2 As Long) As Long

'

End Function

Function FnPtrToLong(ByVal lngFnPtr As Long) As Long

FnPtrToLong = lngFnPtr

End Function

Sub PtrDemo()

Dim l As Long, c As Byte, ca() As Byte, Pt As POINT

Dim pl As Long, pc As Long, pv As Long, pPt As Long, pfnCompare As Long

c = AscB("X")

pl = VarPtr(l) '對應C里的long、int型指針

pc = VarPtr(c) '對應char、short型指針

pPt = VarPtr(Pt) '結構指針

pv = VarPtr(ca(0)) '字節數組指針,可對應任何類型,也就是void*

pfnCompare = FnPtrToLong(AddressOf Compare) '函數指針

CopyMemory c, ByVal pc, LenB(c) '用指針取值

CopyMemory ByVal pc, AscB("Y"), LenB(c) '用指針賦值

pc = pc + LenB(c) : pl = pl - LenB(l) '指針移動

End Sub

我們看到,由于VB不直接支持指針操作,在VB里用指針取值和用指針賦值都必須用CopyMemory這個API,而調用API的代價是比較高的,這就決定了我們在VB里使用指針不能象在C里那樣自由和頻繁,我們必須要考慮指針操作的代價,在后面的"指針應用"我們會再變談這個問題。

程序五中關于函數指針的問題請參考VB文檔,無類型指針void*會在下面"關于Any的問題"里說。

程序五基本上已經包括了我們能在VB里進行的所有指針操作,僅此而已。

下面有一個小測試題,如果現在你就弄懂了上面程咬金的三板斧,你就應該能做得出來。

上面提到過,VB.NET中沒有VarPtr,我們可以用聲明API的方式來引入MSVBVM60.DLL中的VarPtr。現在的問題如果不用VB的運行時DLL文件,你能不能自己實現一個ObjPtr。答案在下一節后給出。

四、指針使用中應注意的問題

1、關于ANY的問題

如果以一個老師的身份來說話,我會說:最好永遠也不要用Any!是的,我沒說錯,是永遠!所以我沒有把它放在程咬金的三板斧里。當然,這個問題和是不是應該使用指針這個問題一樣會引發一場沒有結果的討論,我告訴你的只是一個觀點,因為有時我們會為了效率上的一點點提高或想偷一點點懶而去用Any,但這樣做需要要承擔風險。

Any不是一個真正的類型,它只是告訴VB編譯器放棄對參數類型的檢查,這樣,理論上,我們可以將任何類型傳遞給API。

Any在什么地方用呢?讓我們來看看,在VB文檔里的是怎么說的,現在就請打開MSDN(Visual Studio 6自帶的版本),翻到"Visual Basic文檔"-"使用Visual Basic"-"部件工具指南"-"訪問DLL和Windows API"部分,再看看"將 C 語言聲明轉換為 Visual Basic 聲明"這一節。文檔里告訴我們,只有C的聲明為LPVOID和NULL時,我們才用Any。實際上如果你愿意承擔風險,所有的類型你都可以用Any。當然,也可以如我所說,永遠不要用Any。

為什么要這樣?那為什么VB官方還要提供Any?是信我的,還是信VB官方的?有什么道理不用Any?

如前面所說,VB官方不鼓勵我們使用指針。因為VB所標榜的優點之一,就是沒有危險的指針操作,所以的內存訪問都是受VB運行時庫控制的。在這一點上,JAVA語言也有著同樣的標榜。但是,同JAVA一樣,VB要避免使用指針而得到更高的安全性,就必須要克服沒有指針而帶來的問題。VB已經盡最大的努力來使我們遠離指針的同時擁有強類型檢查帶來的安全性。但是操作系統是C寫的,里面到處都需要指針,有些指針是沒有類型的,就是C程序員常說的可怕的void*無類型指針。它沒有類型,因此它可以表示所有類型。如CopyMemory所對應的是C語言的memcpy,它的聲明如下:

void *memcpy( void *dest, const void *src, size_t count );

因memcpy前兩個參數用的是void*,因此任何類型的參數都可以傳遞給他。

一個用C的程序員,應該知道在C函數庫里這樣的void*并不少見,也應該知道它有多危險。無論傳遞什么類型的變量指針給上面memcpy的void*,C編譯器都不會報錯或給任何警告。

在VB里大多數時候,我們使用Any就是為了使用void*,和在C里一樣,VB也不對Any進行類型檢查,我們也可以傳遞任何類型給Any,VB編譯器也都不會報錯或給任何警告。

但程序運行時會不會出錯,就要看使用它時是不是小心了。正因為在C里很多錯誤是和void*相關的,所以,C++鼓勵我們使用satic_castvoid*來明確指出這種不安全的類型的轉換,已利于發現錯誤。

說了這么多C/C++,其實我是想告訴所有VB的程序員,在使用Any時,我們必須和C/C++程序員使用void*一樣要高度小心。

VB里沒有satic_cast這種東西,但我們可以在傳遞指針時明確的使用long類型,并且用VarPtr來取得參數的指針,這樣至少已經明確地指出我們在使用危險的指針。如程序二經過這樣的處理就成了下面的程序:

【程序五】:

'使用更安全的CopyMemory,明確的使用指針!

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)

Sub SwapStrPtr2(sA As String, sB As String)

Dim lTmp As Long

Dim pTmp As Long, psA As Long, psB As Long

pTmp = VarPtr(lTmp): psA = VarPtr(sA): psB = VarPtr(sB)

CopyMemory pTmp, psA, 4

CopyMemory psA, psB, 4

CopyMemory psB, pTmp, 4

End Sub

注意,上面CopyMemory的聲明,用的是ByVal和long,要求傳遞的是32位的地址值,當我們將一個別的類型傳遞給這個API時,編譯器會報錯,比如現在我們用下面的語句:

【程序六】:

'有點象【程序四】,但將常量40000換成了值為1的變量.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, Length As Long)

Sub TestCopyMemory()

Dim i As Long,k As Long, z As Interger

k = 5 : z = 1

i = VarPtr(k)

'下面的語句會引起類型不符的編譯錯誤,這是好事!

'CopyMemory i, z, 4

'應該用下面的

CopyMemory i, ByVal VarPtr(z), 2

Debug.Print k

End Sub

編譯會出錯!是好事!這總比運行時不知道錯在哪兒好!

象程序四那樣使用Any類型來聲明CopyMemory的參數,VB雖然不會報錯,但運行時結果卻是錯的。不信,你試試將程序四中的40000改為1,結果i的值不是我們想要的1,而是327681。為什么在程序四中,常量為1時結果會出錯,而常量為40000時結果就不錯?

原因是VB對函數參數中的常量按Variant的方式處理。是1時,由于1小于Integer型的最大值32767,VB會生成一個存儲值1的Integer型的臨時變量,也就是說,當我們想將1用CopyMemroy拷貝到Long型的變量i時,這個常量1是實際上是Integer型臨時變量!VB里Integer類型只有兩個字節,而我們實際上拷貝了四個字節。知道有多危險了吧!沒有出內存保護錯誤那只是我們的幸運!

如果一定要解釋一下為什么i最后變成了327681,這是因為我們將k的低16位的值5也拷貝到了i值的高16位中去了,因此有5*65536+1=327681。詳談這個問題涉及到VB局部變量聲明順序,CopyMemory參數的壓棧順序,long型的低位在前高位在后等問題。如果你對這些問題感興趣,可以用本系列第一篇文章所提供的方法(DebugBreak這個API和VC調試器)來跟蹤一下,可以加深你對VB內部處理方式的認識,由于這和本文討論的問題無關,所以就不詳談了。到這里,大家應該明白,程序三和程序四實際上有錯誤!!!我在上面用常量40000而不用1,不是為了在文章中湊字數,而是因為40000這個常量大于32767,會被VB解釋成我們需要的Long型的臨時變量,只有這樣程序三和程序四才能正常工作。對不起,我這樣有意的隱藏錯誤只是想加深你對Any危害的認識。

總之,我們要認識到,編譯時就找到錯誤是非常重要的,因為你馬上就知道錯誤的所在。所以我們應該象程序五和程序六那樣明確地用long型的ByVal的指針,而不要用Any的ByRef的指針。

但用Any已經如此的流行,以至很多大師們也用它。它唯一的魅力就是不象用Long型指針那樣,需要我們自己調用VarPtr來得到指針,所有處理指針的工作由VB編譯器來完成。所以在參數的處理上,只用一條匯編指令:push ,而用VarPtr時,由于需要函數調用,因此要多用五條匯編指令。五條多余的匯編指令有時的確能我們冒著風險去用Any。

VB開發小組提供Any,就是想用ByRef xxx As Any來表達void* xxx。我們也完全可以使用VarPtr和Long型的指針來處理。我想,VB開發小組也曾猶豫過是公布VarPtr,還是提供Any,最后他們決定還是提供Any,而繼續隱瞞VarPtr。的確,這是個兩難的決定。但是經過我上面的分析,我們應該知道,這個決定并不符合VB所追求的"更安全"的初衷。因為它可能會隱藏類型不符的錯誤,調試和找到這種運行時才產生的錯誤將花貴更多的時間和精力。

所以我有了"最好永遠不要用Any"這個"驚人"的結論。

不用Any的另一個好處是,簡化了我們將C聲明的API轉換成VB聲明的方式,現在它變成了一句話:除了VB內置的可以進行類型檢查的類型外,所以其它的類型我們都應該聲明成Long型。

2、關于NULL的容易混淆的問題

有很多文章講過,一定要記在心里:

VbNullChar 相當于C里的'\0',在用字節數組構造C字串時常用它來做最后1個元素。

vbNullString 這才是真正的NULL,就是0,在VB6中直接用0也可以。

只有上面的兩個是API調用中會用的。還有Empty、Null是Variant,而Nothing只和類對象有關,一般API調用中都不會用到它們。

另:本文第三節曾提出一個小測驗題,做出來了嗎?現在公布正確答案:

【測驗題答案】

Function ObjPtr(obj as Object) as long

Dim lpObj As Long

CopyMemory lpObj, Obj, 4

ObjectPtr = lpObj

End Function

五、VB指針應用

如前面所說VB里使用指針不象C里那樣靈活,用指針處理數據時都需要用CopyMemory將數據在指針和VB能夠處理的變量之間來回拷貝,這需要很大的額外開銷。因此不是所有C里的指針操作都可以移值到VB里來,我們只應在需要的時候才在VB里使用指針。

1、動態內存分配:完全不可能、可能但不可行,VB標準

在C和C++里頻繁使用指針的一個重要原因是需要使用動態內存分配,用Malloc或New來從堆棧里動態分配內存,并得到指向這個內存的指針。在VB里我們也可以自己

用API來實現動態分配內存,并且實現象C里的指針鏈表。

但我們不可能象C那樣直接用指針來訪問這樣動態分配的內存,訪問時我們必須用CopyMemory將數據拷貝到VB的變量內,大量的使用這種技術必然會降低效率,以至于要象C那樣用指針來使用動態內存根本就沒有可行性。要象C、PASCAL那樣實現動態數據結構,在VB里還是應該老老實實用對象技術來實現。

本文配套代碼中的LinkedList里有完全用指針實現的鏈表,它是使用HeapAlloc從堆棧中動態分配內存,另有一個調用FindFirstUrlCacheEntry這個API來操作IE的Cache的小程序IECache,它使用了VirtualAlloc來動態分配內存。但實際上這都不是必須的,VB已經為我們提供了標準的動態內存分配的方法,那就是:

對象、字符串和字節數組

限于篇幅,關于對象的技術這里不講,LinkedList的源代碼里有用對象實現的鏈表,你可以參考。

字符串可以用Space$函數來動態分配,VB的文檔里就有詳細的說明。

關于字節數組,這里要講講,它非常有用。我們可用Redim來動態改變它的大小,并將指向它第一個元素的指針傳給需要指針的API,如下:

dim ab() As Byte , ret As long

'傳遞Null值API會返回它所需要的緩沖區的長度。

ret = SomeApiNeedsBuffer(vbNullString)

'動態分配足夠大小的內存緩沖區

ReDim ab(ret) As Byte

'再次把指針

vb和vb.net的區別

VB.NET和VB6.0有什么區別

Visual Basic .NET是Microsoft Visual Studio .NET套件中主要組成部分之一。.NET版本的Visual Basic增加了更多特性,而且演化為完全面向對象(就像C++)的編程語言。本文將介紹VB.NET的新特性,并比較VB6.0/VB.NET之間的區別,闡述如何利用VB.NET編寫簡單的應用程序。

1.1 什么是 VB.NET? Microsoft推出全新的編程和操作系統Framework——.NET,支持多種語言利用公共.NET庫開發應用程序,這些應用程序在.NET Framework上運行。使用Visual Basic在.NET Framework上編程,這就是VB.NET。

首先,讓我演示在VB.NET中寫最簡單的控制臺程序:Hello World。

1.2 Hello, World!“Hello World!”是初學者學習Windows編程的代表性程序。我們的第一個程序就叫做“Hello VB.NET World!”。該程序在控制臺輸出一句話:“Hello VB.NET World!”,代碼如下所示:

代碼 1.1: Hello VB.NET World例子Imports System

Module Module1

Sub Main()

System.Console.WriteLine("Hello VB.NET World!")

End Sub

End Module

1.3 VB.NET 編輯器和編譯器你可以在記事本或VS.NET IDE等任意文本編輯器中撰寫上述代碼,然后保存為HelloWorld.vb。 代碼編寫完成之后,要么在命令行、要么在VS.NET IDE中編譯它。在Microsoft .NET Framework SDK中已經包括VB.NET編譯器vbc.exe[][1],從IDE或是命令行都可以調用。要從命令行編譯HelloWorld.vb,請在命令行窗口輸入

vbc HelloWorld.vb /out:HelloWorld.exe /t:exe

編譯結束后,HelloWorld.exe被創建到當前目錄下。在資源管理其中雙擊圖標或在命令行執行,程序正確地運行了。祝賀你進入VB.NET開發者的行列。

Imports 語句

如你所知,大部分的.NET類型都在名字空間(namespace)中定義。Namespace是定義和管理類別的范疇。察看.NET Framework Class Library,可以看到數以百計的namespace。例如,System namespace就包括了Console、Object等類型定義。如果想使用Console類,需要用Imports指令導入System namespace。如下所示:

Imports System甚至可以明確地調用namespace而無需用Import導入。下面的例子展示了不用Import的“Hello World!”程序:

代碼1.2: Hello VB.NET World例子Module Module1

Sub Main()

System.Console.WriteLine("Hello VB.NET World!")

End SubEnd Module1.4 解析 "Hello VB.NET World!"程序第一行是:

Imports System; System namespace定義了Console類,該類用于讀寫控制臺(命令行窗口)。然后你定義了一個module:Module Module1

…End Module所有的VB程序都包括一個Main()方法,即應用程序入口點。在例子程序中,我們調用Console.WriteLine()向控制臺寫入“Hello VB.NET World!”:

Sub Main()

Console.WriteLine(“Hello VB.NET World!”) End SubWriteLine()方法歸屬于Console類,它負責向控制臺寫一個帶有行結束符的字符串。如前所述,Console類定義于System namespace,你通過直接引用來控制類成員。

Console類負責讀寫系統控制臺。讀控制臺輸入用Read和ReadLine方法,向控制臺輸出用WriteLine方法。

表1.1 Console類定義的方法

方法 用途 例子

Read 讀入單個字符 int i = Console.Read();

ReadLine 讀入一行 string str = Console.ReadLine();

Write 寫一行 Console.Write("Write: 1");

WriteLine 寫一行,并帶上行結束符

Console.WriteLine("Test Output Data with Line");

1.5 VB.NET有什么新特點? VB.NET比 VB6.0更加穩定,而且完全面向對象。也許你還記得,VB6.0不支持繼承、重載和接口,所以不是真正面向對象的。而VB.NET則支持這些面向對象特性。VB6.0有兩個薄弱環節——多線程和異常處理。在VB.NET中,開發多線程應用和使用C++/C#別無二致,結構化異常處理也得到支持。稍后我們會詳細解釋這些特性。

下面是VB.NET的特性列表——

·面向對象的編程語言。支持繼承、重載、接口、共享成員和構造器。·支持所有的CLS特性,如存取控制.NET類、與其它.NET語言交互、元數據、公共數據類型、委托等等。·多線程支持。·結構化異常處理。 1.6 名字空間與集合 前面討論了我們的第一個VB.NET程序。該程序中首先引人注意的是名字空間(namespace)。在.NET參考文檔中,你會發現每個類都歸屬于某個namespace。那么,namespace到底是什么?

一個namespace是類和組件的邏輯組合,其目的在于將.NET class按類別定義。微軟借用了C++ class packaging概念:namespace來描述這種組合。.NET Framework中的組件被稱為集合(assembly)。全部.NET代碼在數百個庫文件(DLL)中定義。Namespace把assembly中定義的類組織起來。一個namespace可以包括多個assembly,一個assembly也可以在多個namespace中定義。 namespace樹的根節點是System namespace。在.NET Library中,每個class都在一組相似的類別中定義。例如,System.Data namespace只包括數據相關類。同樣,System.Multithreading只包括多線程類。

在使用.NET支持的語言(如C#、VB.NET、C++.NET等)創建新應用程序時,你會注意到每個應用程序都被定義為一個namespace,而所有的class都歸屬于這個namespace。通過引用這個namespace,其它應用程序就能存取這些class。 在.NET中,代碼被編譯為中間語言(Intermediate Language,IL),assembly中存儲了IL代碼、元數據和其它資源文件。同一個assembly可以附屬于一個或多個Exe/DLL。所有的.NET庫都存儲在assembly中。

1.7 VB.NET: 完全面向對象的編程語言抽象、封裝、多態、繼承是面向對象語言的四個基本屬性。VB6.0不支持繼承,而VB.NET則不然。所以,和C++一樣,VB.NET也是完全面向對象的編程語言。

Class 和 ModuleVB.NET用Class...End Class語句對創建class。每個VB.NET至少包括一個Module(模塊)。Module在Module…End Module語句對中實現。應用程序的主要模塊是Main方法,亦即應用程序入口點。

和VB6.0相似的地方是,都可以使用Function/Sub關鍵字定義方法。下面的例子顯示了如何創建class、添加方法,并從主程序調用方法: Imports System

Module Module1

Sub Main()

Dim cls As TestClass = New TestClass

Console.WriteLine(cls.MyMethod)

End Sub

Class TestClass

Function MyMethod() As String

Return "Test Method"

End Function

End Class

End ModuleProperty屬性(Property)是類變量的公共描述。Property…End Property語句用以創建property。屬性的Get/Set方法分別用于取得和設置屬性值。下面的例子中,Data是TestClass的屬性。

Imports System

Imports System.Console

Module Module1

Sub Main()

Dim cls As TestClass = New TestClass

WriteLine(cls.MyMethod)

WriteLine(cls.Data)

cls.Data = "New Data"

WriteLine(cls.Data)

End Sub

End Module

Class TestClass

Private strData As String = "Some Data"

Function MyMethod() As String

Return "Test Method!"

End Function

' Adding Data property to the class

Public Property Data() As String

Get

Return strData

End Get

Set(ByVal Value As String)

strData = Value

End Set

End Property

重載VB.NET通過overload關鍵字支持方法重載。使用這個關鍵字,你可以定義同名但不同參數的方法。

類成員訪問域

除了原有的Private和Public,VB.NET引入了幾個新關鍵字。全部訪問域關鍵字列表如下:

關鍵字 作用域

Private 限于class內部

Public 可以從class外訪問

Friend 限于class所屬的應用程序內

Protected 只能被class和其派生類訪問

Protected Friend 能被class、應用程序和派生類訪問

繼承繼承是面向對象編程語言中最常用的技術。繼承讓你能夠重用類代碼和功能。

VB.NET支持繼承,而VB6.0則不支持。繼承的好處在于你能使用任何人編寫的類,從這些類派生自己的類,然后在自己的類中調用父類功能。在下面的例子中,Class B派生自Class A,我們將從Class B中調用Class A的方法MethodA。

Imports System

Imports System.Console

Module Module1

Sub Main()

Dim bObj As B = New B

WriteLine(bObj.MethodA())

End Sub

End Module

' Class A defined

Public Class A

Function MethodA() As String

Return "Method A is called."

End Function

End Class

'Class B, inherited from Class A. All members (Public and Protected)

' can be access via B now.

Public Class B

Inherits A

Function MethodB() As String

Return "Method B is called."

End Function

End Class

可以從一個class中派生多個自定義class,也可以從多個class派生一個自定義class。

共享的成員類的共享成員被類的所有實體共享。共享成員可能是屬性、方法或字段/值域。在你不想讓用戶全面控制自己的類時,共享成員相當有用。例如,你可以開發一個類庫,讓用戶通過共享成員使用其中的部分功能。

可以通過class本身引用共享成員,而無需通過類的實體。例如:Module Module1

Sub Main()

WriteLine(A.MethodA())

End Sub

End Module

' Class A defined

Public Class A

Shared Function MethodA() As String

Return "Method A is called."

End Function

End Class

多線程VB語言的一大弱點就是缺乏編寫自由線程(free-threaded)程序的能力。在.NET Framework中,所有語言共享CRL(Common Runtime Library,公共運行庫),也就是說,你可以用VB.NET、C#或其它.NET語言編寫同樣的程序。

System.Threading namespace定義了線程類。我們只需要引入System.Threading namespace,即可使用線程類。

System.Threading.Thread類提供線程對象,可以使用Thread類創建或破壞線程。

創建線程使用Thread類的實體創建一個新線程,然后用Thread.Start方法開始執行線程。線程構造器接受一個參數,該參數指明你要在線程中執行的procedure。在下例中,我想在oThread1(Thread類的一個實體)的第二線程中執行SecondThread過程:

oThread1 = New Thread(AddressOf SecondThread)

SecondThread procedure looks like below:

Public Sub SecondThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine(i.ToString())

Next

End Sub

然后,調用Thread.Start()開始線程:

oThread1.Start()

下面的代碼創建兩個第二線程:

Imports System

Imports System.Threading

Module Module1

Public oThread1 As Thread

Public oThread2 As Thread

Sub Main()

oThread1 = New Thread(AddressOf SecondThread)

oThread2 = New Thread(AddressOf ThirdThread)

oThread1.Start()

oThread2.Start()

End Sub

Public Sub SecondThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine(i.ToString())

Next

End Sub

Public Sub ThirdThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine("A" + i.ToString())

Next

End Sub

End Module

破壞線程 調用Abort方法來破壞(中止)一個線程。在調用Abort之前,確保用IsAlive判斷線程處于活動狀態。

If oThread1.IsAlive Then

oThread1.Abort()

End If

暫停線程可以使用Sleep方法來暫停線程執行。Sleep方法接受一個以毫秒為單位的參數,指明線程應當暫停多長時間。

下面的例子讓線程暫停1秒鐘:

oThread2.Sleep(1000)你也可以使用Suspend和Resume方法來掛起和繼續線程執行。

設定線程優先級Thread類的Priority屬性用于設定線程優先級。該屬性可以設置為Normal,AboveNormal,BelowNormal,Highest和Lowest。如:

oThread2.Priority = ThreadPriority.Highest線程與Apartment使用ApartmentState屬性設置線程的apartment類型,該屬性值可以為STA,MTA或是Unknown[][2]:

oThread.ApartmentState = ApartmentState.MTAMTS意味著可以使用多線程模式,而STA則只能是單線程執行。

Public Enum ApartmentState

{

STA = 0,

MTA = 1,

Unknown = 2,

}

1.8 結構化異常處理異常處理也被稱之為錯誤處理。作為VB程序員,你一定對On Error Goto和On Error Resume Next這些VB6.0錯誤處理語句耳熟能詳。這種類型的錯誤處理被稱為非結構化異常處理(Unstructured Exception Handling)。而在VB.NET中,Microsoft推出了結構化異常處理機制。VB.NET支持類似C++的TryCatch..Finally控制。Try..Catch..Finally結構如下: Try

' 可能導致異常的代碼

Catch

' 當異常發生時處理異常的代碼

Finally

' 清理現場

End Try

Try語句塊用以拋出異常。如果異常發生,在Catch語句塊中處理。Finally語句塊是可選的,在需要釋放資源時特別有用。

1.9 VB6.0與VB.NET的不同之處除了上面談到的語言進化,還有一些語法上的變化。所有這些語言和語法的變化在MSDN中均可查到,本文只作簡單介紹。

數據類型(Data Type)的改變VB.NET中有些數據類型得到改進。下面是變化對照表。

數據類型 VB6.0 VB.NET

Integer 16 bit size 32 bit size

Long 32 bit size 64 bit size

Currency 用于存儲大浮點數 被decimal替代,支持更高精度

Variant 可以存儲任意類型數據 被Object類型替代,也可以存儲任意類型數據,但結果更好

Date Date類型被存儲為double 引入DateTime類型,用于存儲不同格式的日期

在VB.NET中,Short數據類型是16 bit的。Short,Integer和Long都等同于CLR的System.Int16、System.Int32和System.Int64類型。 變量聲明的變化在VB6.0中,變量聲明有許多限制。其中之一就是不能同行聲明多個變量。如果一定要在一行中聲明多個變量,就一定得指明每個變量的類型,否則將被默認為Variant類型。

Dim a1, a2 As Integer Dim a3 As Integer, a4 As Integer 第一行中的a1是Variant類型,a2是Integer類型。第二行中兩個變量都是Integer類型。VB.NET支持同行聲明多個變量,舉例如下:

Dim a1, a2, a3 As Integer 變量初始化是另一個問題。在VB6.0中不能同時聲明和初始化變量,而VB.NET則支持這個特性。

Dim name As String = "Mahesh"System.Console.Write(name) 聲明常量也可以照此辦理:Const DT_COUNT As Integer = 23 New關鍵字。在VB.NET中,New關鍵字用于創建對象。由于數據類型是對象,所以New關鍵字用以創建一個數據類型對象。

Dim i As Integer = New Integer()i = 10System.Console.WriteLine(i.ToString()) 代碼塊級別支持。像C++一樣,VB.NET支持代碼塊級別的作用域檢查。在語句塊中聲明的變量只在塊內有效。

For i = 1 To 10Dim p As LongSystem.Console.WriteLine(i.ToString())NextSystem.Console.WriteLine(p.ToString()) 這段代碼在VB.NET中會得到一個編譯錯誤,因為p在For..Next語句塊之外不可訪問。在VB6.0中這段代碼可以通過。

改進了的類型安全

在VB6.0中,當你聲明一個對外部過程的引用時,可以指定任意類型的參數為As Any。Any關鍵字禁止了類型檢查,允許任意數據類型傳入和返回。

VB.NET不支持Any關鍵字。你必須指定每個參數和返回值的數據類型。數組VB.NET對數組作了明顯的改動。

數組范圍。在VB.NET中,你需要格外留意數組范圍問題。VB6.0默認數組下界為0,故數組中的元素數量等與數組上界值加一。下面的數組界限從A(0)到A(10),共有11個元素:

Dim A(10) As Single可以使用Option Base改變下界值為1。在VB.NET中,數組和C++一樣,下界值為0,不支持Option Base。注意:MSDN文檔指出數組只能包括與其尺寸相等的元素數量,例如:Dim A(10) As Integer 只能包括10個元素(從A(0)到A(9)),但在編譯下面這段代碼時我發現它運行良好,看起來數組中容納了11個元素。

Dim A(10) As Integer A(0) = 12 A(2) = 24 A(10) = 23 System.Console.WriteLine(A(0).ToString()) System.Console.WriteLine(A(10).ToString())System.Console.WriteLine(UBound(A).ToString()) System.Console.WriteLine(LBound(A).ToString()) Lbound和Ubound分別返回 0與10。ReDim和Fixed Array。你可以在VB6.0中指定固定長度的數組。

Dim ArrWeekDays(0 To 6) As Integer

這里的ArrWeekDays數組是固定長度的,不能用ReDim語句改變長度。VB.NET不支持固定長度數組,所以ReDim總是有效。

可以用下面兩種方式聲明數組: Dim ArrWeekDays(6) As IntegerDim ArrWeekDays() As Integer = {1, 2, 3, 4, 5, 6} ReDim語句。在VB6.0中,ReDim用于初始化動態數組。在VB.NET中你不能把它當作聲明用。ReDim只能用于改變數組長度,不過不能改變數組維度。

Variant對陣ObjectVB6.0中的Variant數據類型能存儲任意類型變量,VB.NET中Object具備相同能力。

算術操作符VB.NET支持類似C++的快捷方式。下面的表格顯示了常規操作與快捷操作的不同之處。快捷方式也可用于*、/、|、等操作符。

操作符 常規語法 快捷方式加法 A = A+5 A +=5 減法 A = A – 5 A -+ 5固定長度字符串

在VB6.0中,可以在聲明字符串時指定其長度。VB.NET不支持固定長度字符串。

布爾操作符VB6.0中的And、Or或是Xor語句是按位操作符。而在VB.NET中,它們是布爾操作符。執行這些操作將返回true或false。VB.NET引入新操作符來完成按位操作。

操作符 描述 BitAnd 按位AndBitOr 按位OrBitXor 按位XorBitNot 按位Not結構與自定義類型在VB6.0中,你使用Type…End Type語句塊創建結構或自定義類型。例如:

Type StdRec

StdId As Integer

StdName As String End Type

VB.NET引入新的語法:Structure。Type…End Type不再被支持。Structure…End Structure與C++用法相同。可以指定結構中每個元素的可訪問域,如Public、Protected、Friend、Protected Friend、Private等。例如:

Structure StdRec

Public StdId As Integer Public StdName As String

Private StdInternal As String End StructureVB.NET中的Structures就像類一樣,也可以擁有方法和屬性。New和Nothing關鍵字VB6.0中,AS New和Nothing關鍵字用于聲明一個對象并初始化它。 VB.NET不支持隱式創建對象。如前所言,甚至連數據類型都是對象。你可以采用以下兩種方法創建數據類型或對象: Dim i As Integer Dim i As Integer = New Integer() // Do something if i = Nothing Then End If 不支持Set語句VB6.0使用Set語句指派對象。例如:Set myObj = new MyObjectSet a = b在VB.NET中,不需要使用Set指派對象。例如:myObj = new MyObj()a = b過程(procedure)語法的變化在VB.NET中過程語法有了很多變化。例如類似C++的過程調用方式、ByVal(傳值)為默認類型、Optional關鍵字、return語句等等。類似C++的過程調用方式 VB6.0允許不用加圓括號調用過程(sub)。不過,用Call語句調用函數或sub時,一定要使用圓括號。例如:Dim I as IntegerCall EvaluateData(2, i) EvaluateData 2, i 在VB.NET中,所有的方法調用都需要圓括號,而Call語句則是可選的。 ByVal是默認參數類型在VB6.0中,在調用函數或sub時ByRef(傳址)是默認類型。那意味著所有改變將反映到傳入的變量。VB.NET改變了這種方式。現在,默認的參數類型是ByVal(傳值)。 Optional關鍵字VB6.0使用Optional關鍵字可用來讓用戶決定傳入一個默認值,之后在調用IsMissing函數判斷參數是否有效。 而在VB.NET中,每個可選參數必須聲明其默認值,無需調用IsMissing函數。例如:Sub MyMethod(Optional ByVal i As Integer = 3)

Return語句VB.NET的Return語句與C++相似。使用Return語句把控制權從過程返還給調用者。在VB6.0中,Return語句與GoSub語句一起使用。VB.NET不再支持GoSub語句。流程控制的改變下面是VB.NET對流程控制語句的修改:1. GoSub不再受到支持。2. Call、Function和Sub語句均可用于調用過程。3. On ... GoSub和On ... GoTo語句不再受支持。可以使用Select Case語句來替代。4. While ... Wend語句現在改為While…End While語句。不再支持Wend關鍵字。小結 Visual Basic .NET是.NET版本的Visual Basic,已經從根本發生了變化!通過本文你了解到VB6.0和VB.NET的區別是很大的,可以說根本就是兩種不同的語言,因為它們的內核發生了變化,VB6.0是基于COM而vb.net是基于.net框架的,因為這個變化,所以在構造類時也發生了根本性的變化。

vb.net UDP 本地發送和接收怎么使用同一個端口呢

DatagramSocket用于接收和發送UDP的Socket實例。該類有3個構造函數:DatagramSocket():通常用于客戶端編程,它并沒有特定監聽的端口,僅僅使用一個臨時的。程序會讓操作系統分配一個可用的端口。DatagramSocket(int port):創建實例,并固定監聽Port端口的報文。通常用于服務端。

新聞名稱:vb.net支持any嗎 vb和net
URL鏈接:http://vcdvsql.cn/article20/hepejo.html

成都網站建設公司_創新互聯,為您提供虛擬主機云服務器定制網站搜索引擎優化移動網站建設Google

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都定制網站網頁設計