Declare 陳述式
更新:2007 年 11 月
宣告在外部檔案中所實作之程序的參考。
[ <attributelist> ] [ accessmodifier ] [ Shadows ] [ Overloads ] _ Declare [ charsetmodifier ] [ Sub ] name Lib "libname" _ [ Alias "aliasname" ] [ ([ parameterlist ]) ] ' -or- [ <attributelist> ] [ accessmodifier ] [ Shadows ] [ Overloads ] _ Declare [ charsetmodifier ] [ Function ] name Lib "libname" _ [ Alias "aliasname" ] [ ([ parameterlist ]) ] [ As returntype ]
參數
attributelist
選擇項。請參閱屬性清單。accessmodifier
選擇項。可以是下列其中一項:請參閱 Visual Basic 中的存取層級。
Shadows
選擇項。請參閱 Shadows。charsetmodifier
選擇項。指定字元集 (Character Set) 和檔案搜尋資訊。可以是下列其中一項:Ansi (預設值)
Sub
選擇項,但必須出現 Sub 或 Function。表示外部程序不會傳回值。Function
選擇項,但必須出現 Sub 或 Function。表示外部程序會傳回值。name
必要項。這個外部參考的名稱。如需詳細資訊,請參閱宣告項目名稱。Lib
必要項。引入 Lib 子句,用於指定包含所宣告之程序的檔案。libname
必要項。包含所宣告程序的檔案名稱。Alias
選擇項。表示所宣告的程序在其檔案內無法按 name 所指定的名稱加以識別。您可以在 aliasname 中指定其識別。aliasname
如果使用 Alias 關鍵字,則為必要項。以下列其中一種方法識別程序的字串:程序在其檔案內的進入點 (Entry Point) 名稱,位於引號 ("") 內
-或-
後面接著整數的數字符號 (#),這個整數會指定程序進入點在其檔案內的序號 (Ordinal Number)
parameterlist
如果程序採用參數,則為必要項。請參閱參數清單。returntype
如果已指定 Function,且 Option Strict 為 On,則為必要項。程序所傳回之值的資料型別。
備註
您有時會需要呼叫在專案外的檔案 (如 DLL 或程式碼資源區) 中所定義的程序。當您這麼做的時候,Visual Basic 編譯器 (Compiler) 無權存取正確呼叫程序所需的資訊,如程序所在位置、識別它的方式、其呼叫順序 (Calling Sequence) 和傳回型別,以及它所使用的字串字元集 (Character Set)。Declare 陳述式會建立外部程序的參考,並提供這項必要資訊。
您只能在模組層級使用 Declare。這表示外部參考的「宣告內容」必須為類別、結構或模組,而不能是原始程式檔 (Source File)、命名空間 (Namespace)、介面、程序或區塊。如需詳細資訊,請參閱宣告內容和預設存取層級。
外部參考會預設值為 Public (Visual Basic) 存取。您可以使用存取修飾詞調整存取層級。
規則
屬性:您可以將屬性套用到外部參考。所套用的屬性只會在您的專案中有作用,在外部檔案中則無作用。
修飾詞 (Modifier)。:外部程序會隱含地 Shared (Visual Basic)。在宣告外部參考時,您無法使用 Shared 關鍵字,因此您無法變更其共用狀態。
外部程序無法參與覆寫、實作介面成員或處理事件。因此,您無法在 Declare 陳述式 (Statement) 中使用 Overrides、Overridable、NotOverridable、MustOverride、Implements 或 Handles 關鍵字。
外部程序名稱:您給與這個外部參考的名稱 (在 name 中) 不必與其外部檔案 (aliasname) 內程序的進入點 (Entry Point) 名稱相同。您可以使用 Alias 子句,指定進入點名稱。如果外部程序與 Visual Basic 保留修飾詞 (Modifier) 同名,或與相同範圍中的變數、程序或任何其他程式設計項目同名,這麼做會很有用。
注意事項: 大部分 DLL 中的進入點名稱都會區分大小寫。
外部程序號碼:此外,您可以使用 Alias 子句,指定外部檔案匯出資料表內之進入點的序號 (Ordinal Number)。若要這麼做,您可以使用數字符號 (#) 做為 aliasname 的開頭。如果 Visual Basic 不允許外部程序名稱中的任何字元,或如果外部檔案匯出沒有名稱的程序,這麼做會很有用。
資料型別規則
參數資料型別:如果 Option Strict 為 On,您必須指定 parameterlist 中每一個參數的資料型別。這可以是任何資料型別,或列舉型別、結構、類別或介面的名稱。在 parameterlist 中,您可以使用 As 子句,指定要傳遞至每一個參數之引數的資料型別。
注意事項: 如果未針對 .NET Framework 撰寫外部程序,您必須注意資料型別要對應。例如,如果您利用 Integer 參數 (在 Visual Basic 6.0 中為 16 位元) 宣告 Visual Basic 6.0 程序的外部參考,則必須將對應引數識別為 Declare 陳述式中的 Short,因為那是 Visual Basic 中的 16 位元整數值。同樣地,Long 在 Visual Basic 6.0 中具有不同的資料寬度,而且會以不同的方式實作 Date。
傳回資料型別:如果外部程序是 Function,且 Option Strict 為 On,則您必須指定已傳回給呼叫程式碼之值的資料型別。這可以是任何資料型別,或列舉型別、結構、類別或介面的名稱。
注意事項: Visual Basic 編譯器並不會驗證您的資料型別是否與外部程序的資料型別相容。如果不符,Common Language Runtime 會在執行階段產生 MarshalDirectiveException 例外狀況。
預設資料型別:如果 Option Strict 為 Off,且您未指定 parameterlist 中參數的資料型別,則 Visual Basic 編譯器會將對應引數轉換為 Object 資料型別。同樣地,如果您未指定 returntype,則編譯器會採用傳回資料型別做為 Object。
注意事項: 因為您所處理的外部程序可能是在不同平台上撰寫,所以對資料型別做出任何假設或允許它們成為預設值是危險的作法。指定每一個參數和傳回值的資料型別 (如果有的話) 是較為安全的作法。這也會增進程式碼的可讀性。
行為
範圍。:外部參考的類別、結構或模組都會在範圍中。
存留期:外部參考與宣告它的類別、結構或模組具有相同的存留期 (Lifetime)。
呼叫外部程序:您可以利用與您呼叫 Function 或 Sub 程序的相同方式呼叫外部程序:如果它會傳回值,則在運算式中使用它;或如果它未傳回值,則在 Call 陳述式 (Visual Basic) 指定它。
您可以完全按照 Declare 陳述式中的 parameterlist 所指定,將引數傳遞至外部程序,不要考慮參數原先如何在外部檔案中宣告。同樣地,如果有一個傳回值,請完全按照 Declare 陳述式中的 returntype 所指定來使用它。
字元集:當 Visual Basic 呼叫外部程序時,您可以在 charsetmodifier 中指定 Visual Basic 應該如何封送處理 (Marshal) 字串。Ansi 修飾詞 (Modifier) 會引導 Visual Basic 將所有字串封送處理為 ANSI 值,而 Unicode 修飾詞則會引導它將所有字串封送處理為 Unicode 值。Auto 修飾詞會根據外部參考 name 或 aliasname (如果有指定的話),引導 Visual Basic 按照 .NET Framework 規則封送處理字串。預設值為 Ansi。
charsetmodifier 也會指定 Visual Basic 應該如何在其外部檔案中查閱外部程序。Ansi 和 Unicode 都會引導 Visual Basic 進行查閱,而不必在搜尋期間修改其名稱。Auto 會引導 Visual Basic 判斷執行階段平台的基底字元集 (Character Set),而且可能會修改外部程序名稱,如下所示:
在 ANSI 平台 (如 Windows 95、Windows 98 或 Windows Millennium Edition) 上,在不修改名稱的情況下,先查閱外部程序。如果失敗的話,請將 "A" 附加到外部程序名稱的尾端,然後再次進行查閱。
在 Unicode 平台 (如 Windows NT、Windows 2000 或 Windows XP) 上,在不修改名稱的情況下,先查閱外部程序。如果失敗的話,請將 "W" 附加到外部程序名稱的尾端,然後再次進行查閱。
機制。:Visual Basic 會使用 .NET Framework「平台叫用」(PInvoke) 機制解析並存取外部程序。Declare 陳述式和 DllImportAttribute 類別兩者都會自動使用這個機制,因此您不需要瞭解 PInvoke。如需詳細資訊,請參閱逐步解說:呼叫 Windows API。
安全性注意事項: |
---|
如果外部程序在 Common Language Runtime (CLR) 外執行,它就是「Unmanaged 程式碼」。當您呼叫此種程序時,例如 Win32 API 函式或 COM 方法,您可能會讓應用程式暴露於安全性風險下。如需詳細資訊,請參閱 Unmanaged 程式碼。 |
範例
下列範例會宣告 Function 程序的外部參考,該程序會傳回目前使用者名稱。接著,它會呼叫外部程序 GetUserNameA 做為 getUser 的一部分。
Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" _
(ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Sub getUser()
Dim buffer As String = New String(CChar(" "), 25)
Dim retVal As Integer = getUserName(buffer, 25)
Dim userName As String = Strings.Left(buffer, InStr(buffer, Chr(0)) - 1)
MsgBox(userName)
End Sub
DllImportAttribute 提供了在 Unmanaged 程式碼中使用函式的另一種方式。下列範例會在不使用 Declare 陳述式的情況下宣告匯入函式。
' Add an Imports statement at the top of the class, structure, or
' module that uses the DllImport attribute.
Imports System.Runtime.InteropServices
<DllImportAttribute("kernel32.dll", EntryPoint:="MoveFileW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function moveFile(ByVal src As String, _
ByVal dst As String) As Boolean
' This function copies a file from the path src to the path dst.
' Leave this function empty. The DLLImport attribute forces calls
' to moveFile to be forwarded to MoveFileW in KERNEL32.DLL.
End Function
請參閱
工作
概念
Visual Basic 6.0 使用者可以進行的資料型別變更