Extern Blocks - Forward Declarations

Extern blocks allow you to declare functions that are defined externally - either in static libraries, inline C++ code, or other external sources. This tells BambooBasic about functions it can call but doesn't define itself.



Basic Syntax

Use Extern...EndExtern blocks to declare external functions:

Extern
Function ExternalFunction:Int(param:String)
Function AnotherFunction()
EndExtern

Alternative lowercase syntax also works:

extern
Function MyExternalFunc:Double(x:Double, y:Double)
endextern


Why Use Extern?

Extern blocks are required when using:

The Extern block tells BambooBasic:



Example with InlineCPP
; Declare the external function first
Extern
Function MyFunc()
EndExtern

Function Main()
    ; Now we can call it
    MyFunc()
    Return False
EndFunction

; Define it in C++
InlineCPP
void MyFunc()
{
    printf("Hello from inline C++\n");
}
EndInlineCPP

The Extern block must come before you call the function.



Example with Linker
; Tell the linker where to find the library
Linker "-L."
Linker "-lmathlib"

; Declare the functions from the library
Extern
Function MathLib_Add:Int(a:Int, b:Int)
Function MathLib_Multiply:Int(a:Int, b:Int)
Function MathLib_Factorial:Int(n:Int)
EndExtern

Function Main()
    Local result:Int = MathLib_Add(5, 3)
    Print "5 + 3 = " & ToString(result)

    Return False
EndFunction


Declaring Functions with Return Values

Specify the return type after the function name using a colon:

Extern
; Returns Int
Function GetValue:Int()

; Returns Double
Function CalculatePi:Double()

; Returns String
Function GetName:String()

; Returns nothing (void)
Function DoWork()
EndExtern


Declaring Functions with Parameters
Extern
; Single parameter
Function ProcessNumber(value:Int)

; Multiple parameters
Function AddNumbers:Int(a:Int, b:Int)

; Mixed types
Function FormatMessage:String(name:String, age:Int, score:Double)

; No parameters
Function Initialize:Int()
EndExtern


Complete Example: Math Library
; Setup linker
Linker "-L."
Linker "-lmathlib"

; Declare all math library functions
Extern
Function MathLib_Add:Int(a:Int, b:Int)
Function MathLib_Subtract:Int(a:Int, b:Int)
Function MathLib_Multiply:Int(a:Int, b:Int)
Function MathLib_Divide:Double(a:Double, b:Double)
Function MathLib_Factorial:Int(n:Int)
Function MathLib_Power:Double(base:Double, exponent:Double)
Function MathLib_SquareRoot:Double(value:Double)
EndExtern

Function Main()
    Print "=== Math Library Test ==="

    ; Addition
    Local sum:Int = MathLib_Add(10, 5)
    Print "10 + 5 = " & ToString(sum)

    ; Division
    Local quotient:Double = MathLib_Divide(10.0, 3.0)
    Print "10 / 3 = " & ToString(quotient)

    ; Factorial
    Local fact:Int = MathLib_Factorial(5)
    Print "5! = " & ToString(fact)

    ; Power
    Local pow:Double = MathLib_Power(2.0, 8.0)
    Print "2^8 = " & ToString(pow)

    ; Square root
    Local sqrt:Double = MathLib_SquareRoot(16.0)
    Print "sqrt(16) = " & ToString(sqrt)

    Return False
EndFunction


Multiple Extern Blocks

You can use multiple Extern blocks in one program:

; Graphics library functions
Extern
Function InitGraphics:Int(width:Int, height:Int)
Function DrawPixel(x:Int, y:Int, color:Int)
Function Flip()
EndExtern

; Audio library functions
Extern
Function LoadSound:Int(filename:String)
Function PlaySound(soundHandle:Int)
Function StopSound(soundHandle:Int)
EndExtern

; Input library functions
Extern
Function IsKeyPressed:Int(keyCode:Int)
Function GetMouseX:Int()
Function GetMouseY:Int()
EndExtern

Function Main()
    InitGraphics(800, 600)

    Local gunshot:Int = LoadSound("gun.wav")

    While True
        If IsKeyPressed(32)  ; Space key
            PlaySound(gunshot)
        EndIf

        Flip()
    Wend

    Return False
EndFunction


Extern with InlineCPP (Advanced)
; Declare multiple C++ functions
Extern
Function Vec2_Create:Int(x:Double, y:Double)
Function Vec2_Length:Double(vec:Int)
Function Vec2_Normalize(vec:Int)
Function Vec2_Dot:Double(vec1:Int, vec2:Int)
Function Vec2_Destroy(vec:Int)
EndExtern

Function Main()
    ; Create vectors
    Local v1:Int = Vec2_Create(3.0, 4.0)
    Local v2:Int = Vec2_Create(1.0, 0.0)

    ; Get length
    Local len:Double = Vec2_Length(v1)
    Print "Vector length: " & ToString(len)

    ; Normalize
    Vec2_Normalize(v1)

    ; Dot product
    Local dot:Double = Vec2_Dot(v1, v2)
    Print "Dot product: " & ToString(dot)

    ; Cleanup
    Vec2_Destroy(v1)
    Vec2_Destroy(v2)

    Return False
EndFunction

InlineCPP
#include 
#include 

struct Vec2 {
    double x, y;
};

static std::map vectors;
static int nextHandle = 1;

int Vec2_Create(double x, double y) {
    Vec2* v = new Vec2{x, y};
    vectors[nextHandle] = v;
    return nextHandle++;
}

double Vec2_Length(int vec) {
    Vec2* v = vectors[vec];
    return sqrt(v->x * v->x + v->y * v->y);
}

void Vec2_Normalize(int vec) {
    Vec2* v = vectors[vec];
    double len = sqrt(v->x * v->x + v->y * v->y);
    if (len > 0) {
        v->x /= len;
        v->y /= len;
    }
}

double Vec2_Dot(int vec1, int vec2) {
    Vec2* v1 = vectors[vec1];
    Vec2* v2 = vectors[vec2];
    return v1->x * v2->x + v1->y * v2->y;
}

void Vec2_Destroy(int vec) {
    delete vectors[vec];
    vectors.erase(vec);
}
EndInlineCPP


Uppercase vs Lowercase

Both syntaxes work identically:

; Uppercase (recommended for consistency)
Extern
Function MyFunc:Int()
EndExtern

; Lowercase (also valid)
extern
Function MyFunc:Int()
endextern

Best Practice: Use uppercase for consistency with other BambooBasic keywords.



Type Compatibility

Make sure the Extern declaration matches the actual function signature:

BambooBasic C/C++ Extern Declaration
Int int Function Foo:Int()
Double double Function Bar:Double()
String const char* Function Baz:String()
Void void Function Qux()


Common Mistakes

1. Forgetting the Extern block:

; WRONG - No Extern declaration
Function Main()
    MyFunc()  ; Error: undefined function
    Return False
EndFunction

InlineCPP
void MyFunc() { printf("Hello\n"); }
EndInlineCPP

Correct:

Extern
Function MyFunc()  ; Declare it first
EndExtern

Function Main()
    MyFunc()  ; Now it works
    Return False
EndFunction

InlineCPP
void MyFunc() { printf("Hello\n"); }
EndInlineCPP

2. Mismatched signatures:

; WRONG - Declaration doesn't match implementation
Extern
Function Add:Int(a:Int, b:Int)
EndExtern

InlineCPP
double Add(double a, double b) {  // Types don't match!
    return a + b;
}
EndInlineCPP

Correct:

Extern
Function Add:Int(a:Int, b:Int)
EndExtern

InlineCPP
int Add(int a, int b) {  // Types match
    return a + b;
}
EndInlineCPP

3. Wrong parameter count:

; WRONG
Extern
Function DoWork(value:Int)
EndExtern

InlineCPP
void DoWork(int value, int extra) {  // Extra parameter!
    // ...
}
EndInlineCPP


Benefits of Extern Blocks

When to Use Extern

Always use Extern when:

Don't use Extern for:



Extern vs Import
Feature Extern Import
Purpose Declare external functions Load DLL declarations
Used With InlineCPP, Linker .decls files
Syntax Extern...EndExtern block Import "file.decls"
Location In your .bam file Separate .decls file


Key Points

See Also

Examples

See the following examples:


BambooBasic © 2026 Michael Denathorn