Declares a prototype for a non-dBL function contained in a DLL file.

Syntax

EXTERN [CDECL | PASCAL | STDCALL ] <return type> <function name>
 ([<parameter type> [, <parameter type> ... ]])
 <filename>

or

EXTERN [CDECL | PASCAL | STDCALL ] <return type> <user-defined function name>
 ([<parameter type> [, <parameter type> ... ]])
 <filename>
 FROM <export function name expC> | <ordinal number expN>

Because you create a function prototype with EXTERN, parentheses are required as with other functions.

CDECL | PASCAL | STDCALL

Sets the function calling convention. The default is STDCALL.

<function name>

The export name of the function. The export name of an external function is contained in the DEF file associated with the DLL file that holds the function, or explicitly exported in the source code.

Note

With STDCALL and CDECL, function names are case-sensitive.

<return type> and <parameter type>

A keyword representing the data type of the value returned by the function, and the data type of each argument you send to the function, respectively. The following tables list the keywords you can use.

 

Parameters or return values

Keyword

as pointer

dBASE Plus
data type

Data Type size

CINT

CPTR CINT

Numeric

4 bytes (32 bits)

CLONG

CPTR CLONG

Numeric

4 bytes (32 bits)

CSHORT

CPTR CSHORT

Numeric

2 bytes (16 bits)

CCHAR

 

Numeric

1 byte (8 bits)

 

CSTRING

String

Null-terminated

CHANDLE

 

Numeric

4 bytes (32 bits)

CUINT

CPTR CUINT

Numeric

4 bytes (32 bits)

CULONG

CPTR CULONG

Numeric

4 bytes (32 bits)

CUSHORT

CPTR CUSHORT

Numeric

2 bytes (16 bits)

CUCHAR

 

Numeric

1 byte (8 bits)

CFLOAT

CPTR CFLOAT

Numeric

4 bytes (32 bits)

CDOUBLE

CPTR CDOUBLE

Numeric

8 bytes (64 bits)

CLDOUBLE

CPTR CLDOUBLE

Numeric

10 bytes (80 bits)

CLOGICAL

CPTR CLOGICAL

Logical

4 bytes (32 bits)

CVOID

 

none

N/A

Parameters only

 

Keyword

as pointer

dBASE Plus
data type

Data Type size

 

CPTR

String

 

...

 

N/A

 

In most cases, if the function expects a pointer as a parameter, dBASE Plus will pass a pointer to the value. If a function returns a pointer, dBASE Plus will get the value at the pointer and convert it into the appropriate dBASE Plus data type.

CCHAR is actually a numeric data type, represeting a single-byte value. When passing a CCHAR parameter, you may pass a string; dBASE Plus sends the ASCII value of the first character in the string. The return value is always a number.

If the function has no parameters or returns no value, declare the data type as CVOID.

You may use the ... parameter declaration if the calling convention is STDCALL to designate a variable number of parameters.

Using strings

dBASE Plus is a Unicode application; using strings is more complicated in 32-bit programming than in 16-bit programming. Many Windows API functions have both an A (ANSI) and W (wide-character) version. The A functions use single-byte characters, and the W versions use double-byte characters. When calling the A version of a function, always use CSTRING. When calling the W version of a function, always use CPTR. When you use CSTRING, dBASE Plus will convert the Unicode string it uses into an ANSI string when passing it to the function. After the function call, it converts the ANSI string back into Unicode. With CPTR, no conversion takes place.

When strings (CSTRING or CPTR) are used as parameters, they are always passed and read back by length. You may include null characters in the string. When a return value is declared as CSTRING, it is read as null-terminated. You cannot use CPTR as a return value.

Using structures

If the function expects a pointer to a structure, declare the parameter as CPTR. Use a string to represent the structure contents. Because dBASE Plus strings are Unicode, you must use the String object’s getByte( ) and setByte( ) methods to read and write the structure, byte-by-byte.

<filename>

The name of the DLL file in which the external function is stored. If the extension is omitted, the default is DLL. The file name of any DLL that you load in memory must be unique; for example, you can't load SCRIPT.DLL and SCRIPT.FON into memory concurrently, even though they have different file-name extensions.

If the DLL file is not already loaded into memory, EXTERN loads it automatically. If the DLL file is already in memory, EXTERN increments the reference counter. Therefore, it isn't necessary to execute LOAD DLL before using EXTERN.

The reference counter is incremented only the first time, regardless of how many times you execute the LOAD DLL and EXTERN statements.

You may include a path in <filename>. If you omit the path, dBASE Plus looks in the following directories for the DLL by default:

  1. The directory containing PLUS.exe, or the directory in which the .EXE file of your compiled application is located.

  2. The current directory.

  3. The 32-bit Windows system directory (for example, C:\WIN95\SYSTEM).

  4. The 16-bit Windows system directory, if present (for example, C:\WINDOWS\SYSTEM).

  5. The Windows directory (for example, C:\WINNT)

  6. The directories in the PATH environment variable

The path specification is necessary only when the DLL file is not in one of these directories.

<user-defined function name>

The name you give to the external function instead of the export name. This is usually used to rename the A or W version of a function to the generic name. When you specify <user-defined function name> (instead of <function name>), you must use the FROM clause to identify the function in the DLL file.

FROM <export function name expC> | <ordinal number expN>

Identifies the function in the DLL file specified by <filename>. <export function name expC> identifies the function by its name. <ordinal number expN> identifies the function with a number.

Description

Use EXTERN to declare a prototype for an external function written in a language other than dBL. A prototype tells dBASE Plus to convert its arguments to data types the external function can use, and to convert the value returned by the external function into a data type dBASE Plus can use.

To call an external DLL function, first prototype it with EXTERN. Then, using the name of the function you specified with EXTERN, call the function as you would any dBL function. You must prototype an external function before you can call that function in dBASE Plus.

The external function may be in any 32-bit DLL, such as the Windows API or a third-party DLL file. Although most library code is contained in files with extensions of DLL, such code can be held in EXE files, or even in DRV or FON files.