Declares a reference to a procedure implemented in an external file.
[ <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 ]
||Optional. See Attribute List.|
||Optional. Can be one of the following:
- Protected Friend
- Private Protected
See Access levels in Visual Basic.
||Optional. See Shadows.|
||Optional. Specifies character set and file search information. Can be one of the following:
- Ansi (default)
||Optional, but either
||Optional, but either
||Required. Name of this external reference. For more information, see Declared Element Names.|
||Required. Introduces a
||Required. Name of the file that contains the declared procedure.|
||Optional. Indicates that the procedure being declared cannot be identified within its file by the name specified in
||Required if you use the
The entry point name of the procedure within its file, within quotes (
A number sign (
||Required if the procedure takes parameters. See Parameter List.|
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.
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
Sharedkeyword 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
Handleskeyword in a
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 an
Aliasclause 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.
Entry-point names in most DLLs are case-sensitive.
External Procedure Number. Alternatively, you can use an
Aliasclause to specify the ordinal number of the entry point within the export table of the external file. To do this, you begin
aliasnamewith 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
On, you must specify the data type of each parameter in
parameterlist. This can be any data type or the name of an enumeration, structure, class, or interface. Within
parameterlist, you use an
Asclause to specify the data type of the argument to be passed to each parameter.
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
Integerparameter (16 bits in Visual Basic 6.0), you must identify the corresponding argument as
Declarestatement, because that is the 16-bit integer type in Visual Basic. Similarly,
Longhas a different data width in Visual Basic 6.0, and
Dateis implemented differently.
Return Data Type. If the external procedure is a
On, 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.
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
Offand you do not specify the data type of a parameter in
parameterlist, the Visual Basic compiler converts the corresponding argument to the Object Data Type. Similarly, if you do not specify
returntype, the compiler takes the return data type to be
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.
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
Subprocedure—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
Declarestatement. 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 by
Character Sets. You can specify in
charsetmodifierhow Visual Basic should marshal strings when it calls the external procedure. The
Ansimodifier directs Visual Basic to marshal all strings to ANSI values, and the
Unicodemodifier directs it to marshal all strings to Unicode values. The
Automodifier directs Visual Basic to marshal strings according to .NET Framework rules based on the external reference
aliasnameif specified. The default value is
charsetmodifieralso specifies how Visual Basic should look up the external procedure within its external file.
Unicodeboth direct Visual Basic to look it up without modifying its name during the search.
Autodirects 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
Declarestatement 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.
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.
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
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
The DllImportAttribute provides an alternative way of using functions in unmanaged code. The following example declares an imported function without using a
' 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