DECLARE (External Functions)

Syntax

Syntax: DECLARE FUNCTION|SUB name LIB "dll" ALIAS "export" ([BYVAL|BYREF] param AS type, ...) AS rettype
Source: PB parser + import table generator

Description

Declares an external function or subroutine from a DLL so it can be called with CALL. The compiler generates entries in the PE32+ import table (.idata section) for each declared function. At load time, the Windows PE loader resolves these entries to actual DLL addresses. Multiline parameter lists with _ continuation are supported for readability.

Parameters

ParameterDescription
FUNCTION|SUBUse FUNCTION if the DLL export returns a value, SUB if it returns void.
nameThe name used in your PowerBASIC code to call this function.
LIB "dll"The DLL filename (e.g., "user32.dll"). The PE loader searches standard system paths.
ALIAS "export"The actual exported function name in the DLL. Use this when the PB name differs from the DLL export name.
BYVAL param AS typeA parameter passed by value. The value itself is placed in the register or stack slot.
BYREF param AS typeA parameter passed by reference. A pointer to the variable is placed in the register or stack slot.
AS rettypeThe return type for FUNCTIONS. Omitted for SUBs. Common types: LONG, QUAD, STRING, SINGLE, DOUBLE.

Example

DECLARE FUNCTION MessageBoxA LIB "user32.dll" _
    ALIAS "MessageBoxA" ( _
    BYVAL hWnd AS QUAD, _
    BYVAL lpText AS ASCIIZ PTR, _
    BYVAL lpCaption AS ASCIIZ PTR, _
    BYVAL uType AS LONG _
) AS LONG

DECLARE FUNCTION GetTickCount LIB "kernel32.dll" _
    ALIAS "GetTickCount" () AS DWORD

FUNCTION PBMAIN() AS LONG
    LOCAL ticks AS DWORD
    
    ticks = GetTickCount()
    PRINT "System uptime: "; ticks; " ms"
    
    CALL MessageBoxA(0, "Hello World", "PB x64", 0)
    
    FUNCTION = 0
END FUNCTION

Generated Assembly

Import Table (.idata section)

; Import Directory Table entry for user32.dll:
dq    __imp_MessageBoxA

; Import Address Table (IAT) entry:
__imp_MessageBoxA:
    dq    0                           ; resolved at load time by Windows PE loader

; Import Name Table (INT) entry:
    dw    0                           ; hint
    db    "MessageBoxA", 0            ; function name

Calling a Declared Function

; Evaluate arguments and stage them according to Win64 ABI:
mov    rcx, 0                         ; hWnd -> RCX
lea    rdx, [__pb_str_hello]          ; lpText -> RDX
lea    r8,  [__pb_str_cap]            ; lpCaption -> R8
mov    r9, 0                          ; uType -> R9

; Call the function via the IAT pointer:
call   [__imp_MessageBoxA]            ; indirect call through import table

; Return value is in RAX (integer) or XMM0 (float)
mov    rax, rax                       ; result is already in RAX

Supported Parameter Types

PB TypeC EquivalentSizeRegister/Stack
LONGint32_t4Integer register
QUADint64_t / void*8Integer register
BYTEuint8_t1Integer register
WORDuint16_t2Integer register
DWORDuint32_t4Integer register
SINGLEfloat4XMM register
DOUBLEdouble8XMM register
STRINGchar* (ASCIIZ)8Integer register (ptr)
ASCIIZ PTRconst char*8Integer register (ptr)

Limitations