Declare Statement

宣告實作在外部檔案中之程序的參考。

語法

[ <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 選擇性。 可以是下列其中一項:

- 公開
- Protected
- Friend
- 私用
- Protected Friend
- Private Protected

請參閱 Access levels in Visual Basic
Shadows 選擇性。 請參閱 Shadows
charsetmodifier 選擇性。 指定字元集和檔案搜尋的資訊。 可以是下列其中一項:

- Ansi (預設)
- Unicode
- Auto
Sub (選擇性) 但 SubFunction 必須出現。 表示外部程序不會傳回值。
Function (選擇性) 但 SubFunction 必須出現。 表示外部程序會傳回值。
name 必要。 此外部參考的名稱。 如需詳細資訊,請參閱宣告元素名稱
Lib 必要。 引進能找出包含外部程序中外部檔案 (DLL 或程式碼資源) 的 Lib 子句。
libname 必要。 包含宣告程續的檔案名稱。
Alias 選擇性。 表示所宣告的程序無法透過 name 中指定的名稱在其檔案中進行識別。 您可以在 aliasname 中指定其身分識別。
aliasname 使用 Alias 關鍵字時的必要項目。 以下列兩種方式其中之一識別程序的字串:

程序在其檔案內的進入點名稱,在引號內 ("")

-或-

數字符號 (#) 後面接著一個整數,指定程序在其檔案中的進入點序號
parameterlist 如果程式採用參數,則此為必要項目。 請參閱參數清單
returntype 如果指定 FunctionOption StrictOn,則為必要項目。 此程序所傳回值的資料類型。

備註

有時候您需要呼叫專案外部檔案中定義的程序 (例如 DLL 或程式碼資源)。 您執行此動作時,Visual Basic 編譯器無法存取其正確呼叫程式所需的資訊,例如程式所在的位置、識別方式、其呼叫順序和傳回類型,以及使用的字串字元集。 Declare 陳述式會建立對外部程序的參考,並提供此必要資訊。

您只能在模組層級使用 Declare。 這表示針對外部參考的「宣告內容」必須是類別、結構、模組或介面,且不能是來源檔案、命名空間、介面、程序或區塊。 如需詳細資訊,請參閱宣告內容和預設存取層級

外部參考預設為公用存取。 您可使用存取修飾詞來調整其存取層級。

規則

  • 屬性。 您可以將屬性套用至外部參考。 您套用的任何屬性只會在專案中生效,並不會在外部檔案中生效。

  • 修飾詞。 外部程序會隱含共用。 您無法在宣告外部參考時使用 Shared 關鍵字,而且無法改變其共用狀態。

    外部程序無法參與覆寫、實作介面成員或處理事件。 因此您無法在 Declare 陳述式中使用 OverridesOverridableNotOverridableMustOverrideImplementsHandles 關鍵字。

  • 外部程序名稱。 您不需要 (在 name 中) 為此外部參考提供與程式外部檔案 (aliasname) 內進入點名稱相同的名稱。 您可以使用 Alias 子句來指定進入點名稱。 如果外部程式的名稱與 Visual Basic 保留修飾詞或變數、程式或任何其他相同範圍中程式設計元素的名稱相同,這非常有用。

    注意

    大部分 DLL 中的進入點名稱會區分大小寫。

  • 外部程序編號。 或者您可以使用 Alias 子句來指定外部檔案匯出資料表內進入點的編號。 若要執行此動作,請從具數字符號 (#) 的 aliasname 開始。 如果 Visual Basic 中不允許外部程序名稱中的任何字元,或外部檔案要匯出沒有名稱的程序,這非常有用。

資料類型規則

  • 參數資料類型。 如果 Option StrictOn,則您必須指定在 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

  • 傳回資料類型。 如果外部程序為 FunctionOption StrictOn,您必須指定傳回給呼叫程式碼值的資料類型。 此項目可以是任何資料類型,或是列舉、結構、類別或介面的名稱。

    注意

    Visual Basic 編譯器不會驗證您的資料類型是否與外部程序的資料類型相容。 如果不相符,Common Language Runtime 會在執行時間產生 MarshalDirectiveException 例外狀況。

  • 預設資料類型。 如果 Option StrictOff,且您未在 parameterlist 中指定參數的資料類型,Visual Basic 編譯器會將對應的引數轉換為 Object 資料類型。 同樣地,如果您未指定 returntype,編譯器會將傳回資料類型視為 Object

    注意

    由於您正在處理可能已在不同平台上撰寫的外部程序,因此對資料類型進行任何假設或允許該資料類型為預設十分危險。 如果可以的話,指定每個參數和傳回值的資料類型會比較安全。 這也可改善程式碼的可讀性。

行為

  • [範圍]。 外部參考在其類別、結構或模組的範圍內。

  • 存留期。 外部參考的存留期與宣告此參考的類別、結構或模組存留期相同。

  • 呼叫外部程序。 您呼叫外部程序的方式與呼叫 FunctionSub 程序的方式相同,方法是在運算式中使用此項目傳回值,不會傳回值則在 Call 陳述式中指定此項目。

    您會將引數傳遞至與 Declare 陳述式中 parameterlist 指定的完全一樣外部程式。 請勿參考參數最初在外部檔案中宣告的方式。 同樣地,如果有傳回值,請以與 Declare 陳述式中 returntype 所指定的方式使用此值。

  • 字元集。 您可以在 charsetmodifier Visual Basic 呼叫外部程序時,指定封送處理字串的方式。 Ansi 修飾詞會指示 Visual Basic 將所有字串封送處理至 ANSI 值,而 Unicode 修飾詞會將所有字串封送處理至 Unicode 值。 Auto 修飾詞會指示 Visual Basic 根據基於外部參考 name (或是指定 aliasname) 的 .NET Framework 規則封送處理字串。 預設值是 Ansi

    charsetmodifier 也會指定 Visual Basic 如何查閱其外部檔案內的外部程序。 AnsiUnicode 都會引導 Visual Basic 在搜尋期間進行查詢,而不需修改其名稱。 Auto 指示 Visual Basic 判斷執行時間平台的基底字元集,並可能修改外部程序名稱,如下所示:

    • 在 Unicode 平台上,例如 Windows,先查閱未修改名稱的外部程序。 如果失敗,請將「W」附加至外部程序名稱的結尾,然後再次查閱。

    • 在 ANSI 平台上,先查閱未修改名稱的外部程序。 如果失敗,請將「A」附加至外部程序名稱的結尾,然後再次查閱。

  • 機制。 Visual Basic 使用 .NET Framework 平台叫用 (PInvoke) 機制來解析和存取外部程序。 Declare 陳述式和 DllImportAttribute 類別都會自動使用此機制,而且您不需要任何 PInvoke 的知識。 如需詳細資訊,請參閱逐步解說:呼叫 Windows API

重要

如果外部程序是在 Common Language Runtime (CLR) 外執行,則此程序為非受控程式碼。 當您呼叫這類程序時,例如 Windows API 函式或 COM 方法,可能會將您的應用程式暴露在安全性風險中。 如需詳細資訊,請參閱非受控程式碼的安全編碼指導方針

範例 1

下列範例會宣告傳回目前使用者名稱 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

範例 2

DllImportAttribute 提供在非受控程式碼中使用函式的替代方式。 下列範例會宣告匯入的函式,無需使用 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

另請參閱