Skip to content
AnatineSquire40 edited this page May 1, 2026 · 26 revisions

LuIbexWin --- Complete Cheat-Sheet

Main Functions

To require it, do: require"ibexwin.h"

ToWindowProc( [userdata] hWnd, [callable_func] lfnc) -> userdata

Converts a Lua function into a Win32 WNDPROC. Keeps the closure alive. [Important: if the garbage collector collects the closure while the window is still active, the WNDPROC becomes invalid and your application may crash.]

Num2Addr(int) -> userdata

Converts an integer into userdata representing a pointer.

Addr2Num(userdata) -> int

Converts a userdata containing a pointer into an integer.

Val2Addr( [any] arg1, [int] arg2, [bool] arg3 )

Creates a memory/userdata block from a Lua value:

  • Int, Number, Boolean → simple copy
Val2Addr( [int/bool/number] val ) -> userdata
  • Nil + size → empty buffer
Val2Addr( nil, [int] size, [opt, bool] rawmem ) -> string -- if rawmem is true then -> userdata

Addr2Val Native Function

Addr2Val( [userdata] nativeFuncPtr, [string] returnType, [table] argTypes, [opt, callable_func] trampolineCallback, [opt, callable_func] clean) -> lfnc

Converts a native function pointer into a safe Lua closure. LuIbexWin internally handles up to 16 arguments. [Arguments beyond this limit will raise an error.] The trampoline callback args are this:

function trampolineCallback( [userdata] func_addr, [table] argttable , [userdata] argsany, [userdata] argsdouble, [userdata] argsfloat32, [bool]
isret_double, [bool] isret_float32, [int] nargs) -> 
[userdata] (void*/double/float(*native_function)() -> void*/double/float)

The trampoline callback replaces the internal dispatcher completely.

The default dispatcher is responsible for:

· selecting the correct function signature based on argument names · resolving how parameters must be interpreted for the call · preparing the runtime call context (register/stack layout metadata) · performing a direct invocation without generating any executable stub

This callback allows you to fully override the dispatch process and instead return a custom generated trampoline (executable stub) ready for direct execution.

The clean callback args are this:

function clean( [userdata] native_function )

The clean callback is executed after the native call finishes.

Used to free or invalidate the generated trampoline code, preventing memory leaks from dynamically allocated executable stubs.

Addr2Val Read Memory

Addr2Val(userdata, [string] valueType) -> anyValue

Reads memory from a pointer and returns the specified Lua type. Supports basic types and pointers; any invalid access produces a safe Lua error instead of crashing.

CopyAddr( [userdata | string] src, [int] size, [opt, bool] switch ) -> userdata | string

Copies a fixed number of bytes from a source string or userdata into a new buffer. The return type depends on the source type and the optional switch flag, allowing conversion between raw memory (userdata) and Lua strings. All memory accesses are protected; invalid reads raise a Lua error instead of crashing the process.

WriteAddr( [userdata] dest, [userdata | string] src, [int] size)

Returns the raw address of the current lua_State as a lightuserdata value. This exposes the internal Lua state pointer for advanced native integration, debugging, or low-level hooking. No validation or safety checks are performed beyond type wrapping.

LoopMessages() -> boolean

Processes the Windows message queue until the application closes. Returns true if it finishes correctly, or nil and an error code if it fails.

[Internally, closures registered as WinProc receive the messages and must return DefWindowProc if unhandled. LuIbexWin automatically routes messages by HWND and class name.]

Type Aliases

  • i or integer
  • d or double
  • f or float
  • s or string
  • u or userdata
  • b or boolean
  • p or lightuserdata
  • v or void

Common Constants and Macros

  • MB_OK, MB_YESNO - MessageBox types
  • WS_OVERLAPPEDWINDOW, WS_CHILD, WS_VISIBLE - Window styles
  • SW_SHOW, SW_HIDE - ShowWindow commands
  • COLOR_WINDOW, COLOR_BTNFACE - Predefined colors
  • IDC_ARROW, IDC_HAND - Predefined cursors
  • IDI_APPLICATION, IDI_WARNING - Predefined icons
  • CS_HREDRAW, CS_VREDRAW - Window class styles
  • WM_DESTROY, WM_COMMAND - Window messages

Advanced Tips and Safety

  • LuIbexWin uses SEH (__try/__except) so memory faults don't crash Lua.
  • Keep alive the closures you pass to Win32 while the window exists.
  • Value references are managed via Val2Addr to pass and update memory directly.
  • Avoid passing more than 16 arguments to Addr2Val for native functions.
  • Return DefWindowProc in callbacks if a message is not handled.
  • LuIbexWin routes messages by HWND and class name automatically, allowing multiple controls without conflicts.
  • You don't need to specify sizeof for standard structs (RECT, POINT, WINDOWPLACEMENT).

Quick Example

    require"ibexwin.h"
    local k32 = GetModuleHandle("kernel32.dll")
    local GetTickCount_addr = GetProcAddress(k32, "GetTickCount")
    local gettick = Addr2Val(Num2Addr(GetTickCount_addr), "integer", {})
    print("Ticks:", gettick())

    local nameBuf, bufsz = Val2Addr(nil, 256)
    local sizeRef = Val2Addr(bufsz)
    local getComputerName = Addr2Val(
        Num2Addr(GetProcAddress(k32,"GetComputerNameA")),
        "boolean",
        {"string","lightuserdata"}
    )
    if getComputerName(nameBuf, sizeRef) then
        print("PC:", nameBuf)
    end

Minimal Window Example in Lua with LuIbexWin

    require "ibexwin.h"

    local function onButtonClick(hwnd)
        MessageBox(hwnd, "Hello world!", "My first window", MB_OK)
    end

    local winProc = function(hWnd, uMsg, wParam, lParam)
        if uMsg == WM_DESTROY then
            PostQuitMessage(0)
            return 0
        elseif uMsg == WM_COMMAND then
            if LOWORD(wParam) == 1001 then
                onButtonClick(hWnd)
            end
        end
        return DefWindowProc(hWnd, uMsg, wParam, lParam)
    end

    local CLASS_NAME = "LuaClass"
    local wc = {
        style = CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc = winProc,
        cbClsExtra = 0,
        cbWndExtra = 0,
        hInstance = GetModuleHandle(nil),
        hIcon = nil,
        hCursor = LoadCursor(nil, IDC_ARROW),
        hbrBackground = COLOR_WINDOW+1,
        lpszMenuName = nil,
        lpszClassName = CLASS_NAME,
        hIconSm = nil
    }
    RegisterClassEx(wc)

    local hwnd = CreateWindow(
        CLASS_NAME,
        "Hello World from Lua",
        WS_OVERLAPPEDWINDOW,
        100, 100, 400, 300,
        nil, nil,
        wc.hInstance
    )

    local hButton = CreateWindow(
        "BUTTON",
        "Click me",
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        50, 50, 100, 30,
        hwnd,
        1001,
        wc.hInstance
    )

    ShowWindow(hwnd, SW_SHOW)
    UpdateWindow(hwnd)
    LoopMessages()

This example creates a simple window with a button. LoopMessages() processes events. Message routing and closure management are handled internally by LuIbexWin.