Declare Statement
Declares a reference to a procedure implemented in an external file.
Syntax
[ <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 ]
Parts
Term | Definition |
---|---|
attributelist |
Optional. See Attribute List. |
accessmodifier |
Optional. Can be one of the following: - Public - Protected - Friend - Private - Protected Friend - Private Protected See Access levels in Visual Basic. |
Shadows |
Optional. See Shadows. |
charsetmodifier |
Optional. Specifies character set and file search information. Can be one of the following: - Ansi (default) - Unicode - Auto |
Sub |
Optional, but either Sub or Function must appear. Indicates that the external procedure does not return a value. |
Function |
Optional, but either Sub or Function must appear. Indicates that the external procedure returns a value. |
name |
Required. Name of this external reference. For more information, see Declared Element Names. |
Lib |
Required. Introduces a Lib clause, which identifies the external file (DLL or code resource) that contains an external procedure. |
libname |
Required. Name of the file that contains the declared procedure. |
Alias |
Optional. Indicates that the procedure being declared cannot be identified within its file by the name specified in name . You specify its identification in aliasname . |
aliasname |
Required if you use the Alias keyword. String that identifies the procedure in one of two ways:The entry point name of the procedure within its file, within quotes ( "" )-or- A number sign ( # ) followed by an integer specifying the ordinal number of the procedure's entry point within its file |
parameterlist |
Required if the procedure takes parameters. See Parameter List. |
returntype |
Required if Function is specified and Option Strict is On . Data type of the value returned by the procedure. |
Remarks
Sometimes you need to call a procedure defined in a file (such as a DLL or code resource) outside your project. When you do this, the Visual Basic compiler does not have access to the information it needs to call the procedure correctly, such as where the procedure is located, how it is identified, its calling sequence and return type, and the string character set it uses. The Declare
statement creates a reference to an external procedure and supplies this necessary information.
You can use Declare
only at module level. This means the declaration context for an external reference must be a class, structure, or module, and cannot be a source file, namespace, interface, procedure, or block. For more information, see Declaration Contexts and Default Access Levels.
External references default to Public access. You can adjust their access levels with the access modifiers.
Rules
Attributes. You can apply attributes to an external reference. Any attribute you apply has effect only in your project, not in the external file.
Modifiers. External procedures are implicitly Shared. You cannot use the
Shared
keyword when declaring an external reference, and you cannot alter its shared status.An external procedure cannot participate in overriding, implement interface members, or handle events. Accordingly, you cannot use the
Overrides
,Overridable
,NotOverridable
,MustOverride
,Implements
, orHandles
keyword in aDeclare
statement.External Procedure Name. You do not have to give this external reference the same name (in
name
) as the procedure's entry-point name within its external file (aliasname
). You can use anAlias
clause to specify the entry-point name. This can be useful if the external procedure has the same name as a Visual Basic reserved modifier or a variable, procedure, or any other programming element in the same scope.Note
Entry-point names in most DLLs are case-sensitive.
External Procedure Number. Alternatively, you can use an
Alias
clause to specify the ordinal number of the entry point within the export table of the external file. To do this, you beginaliasname
with a number sign (#
). This can be useful if any character in the external procedure name is not allowed in Visual Basic, or if the external file exports the procedure without a name.
Data Type Rules
Parameter Data Types. If
Option Strict
isOn
, you must specify the data type of each parameter inparameterlist
. This can be any data type or the name of an enumeration, structure, class, or interface. Withinparameterlist
, you use anAs
clause to specify the data type of the argument to be passed to each parameter.Note
If the external procedure was not written for the .NET Framework, you must take care that the data types correspond. For example, if you declare an external reference to a Visual Basic 6.0 procedure with an
Integer
parameter (16 bits in Visual Basic 6.0), you must identify the corresponding argument asShort
in theDeclare
statement, because that is the 16-bit integer type in Visual Basic. Similarly,Long
has a different data width in Visual Basic 6.0, andDate
is implemented differently.Return Data Type. If the external procedure is a
Function
andOption Strict
isOn
, you must specify the data type of the value returned to the calling code. This can be any data type or the name of an enumeration, structure, class, or interface.Note
The Visual Basic compiler does not verify that your data types are compatible with those of the external procedure. If there is a mismatch, the common language runtime generates a MarshalDirectiveException exception at run time.
Default Data Types. If
Option Strict
isOff
and you do not specify the data type of a parameter inparameterlist
, the Visual Basic compiler converts the corresponding argument to the Object Data Type. Similarly, if you do not specifyreturntype
, the compiler takes the return data type to beObject
.Note
Because you are dealing with an external procedure that might have been written on a different platform, it is dangerous to make any assumptions about data types or to allow them to default. It is much safer to specify the data type of every parameter and of the return value, if any. This also improves the readability of your code.
Behavior
Scope. An external reference is in scope throughout its class, structure, or module.
Lifetime. An external reference has the same lifetime as the class, structure, or module in which it is declared.
Calling an External Procedure. You call an external procedure the same way you call a
Function
orSub
procedure—by using it in an expression if it returns a value, or by specifying it in a Call Statement if it does not return a value.You pass arguments to the external procedure exactly as specified by
parameterlist
in theDeclare
statement. Do not take into account how the parameters were originally declared in the external file. Similarly, if there is a return value, use it exactly as specified byreturntype
in theDeclare
statement.Character Sets. You can specify in
charsetmodifier
how Visual Basic should marshal strings when it calls the external procedure. TheAnsi
modifier directs Visual Basic to marshal all strings to ANSI values, and theUnicode
modifier directs it to marshal all strings to Unicode values. TheAuto
modifier directs Visual Basic to marshal strings according to .NET Framework rules based on the external referencename
, oraliasname
if specified. The default value isAnsi
.charsetmodifier
also specifies how Visual Basic should look up the external procedure within its external file.Ansi
andUnicode
both direct Visual Basic to look it up without modifying its name during the search.Auto
directs Visual Basic to determine the base character set of the run-time platform and possibly modify the external procedure name, as follows:On a Unicode platform, such as Windows, first look up the external procedure with no name modification. If that fails, append "W" to the end of the external procedure name and look it up again.
On an ANSI platform, first look up the external procedure with no name modification. If that fails, append "A" to the end of the external procedure name and look it up again.
Mechanism. Visual Basic uses the .NET Framework platform invoke (PInvoke) mechanism to resolve and access external procedures. The
Declare
statement and the DllImportAttribute class both use this mechanism automatically, and you do not need any knowledge of PInvoke. For more information, see Walkthrough: Calling Windows APIs.
Important
If the external procedure runs outside the common language runtime (CLR), it is unmanaged code. When you call such a procedure, for example a Windows API function or a COM method, you might expose your application to security risks. For more information, see Secure Coding Guidelines for Unmanaged Code.
Example 1
The following example declares an external reference to a Function
procedure that returns the current user name. It then calls the external procedure GetUserNameA
as part of the getUser
procedure.
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
Example 2
The DllImportAttribute provides an alternative way of using functions in unmanaged code. The following example declares an imported function without using a Declare
statement.
' 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