Repository navigation
Home
To require it, do: require"ibexwin.h"
ToWindowProc( [userdata] hWnd, [callable_func] lfnc) -> userdataConverts 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) -> userdataConverts an integer into userdata representing a pointer.
Addr2Num(userdata) -> intConverts 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 -> userdataAddr2Val( [userdata] nativeFuncPtr, [string] returnType, [table] argTypes, [opt, callable_func] trampolineCallback, [opt, callable_func] clean) -> lfncConverts 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(userdata, [string] valueType) -> anyValueReads 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 | stringCopies 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() -> booleanProcesses 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.]
-
iorinteger -
dordouble -
forfloat -
sorstring -
uoruserdata -
borboolean -
porlightuserdata -
vorvoid
-
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
- 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
Val2Addrto pass and update memory directly. - Avoid passing more than 16 arguments to
Addr2Valfor native functions. - Return
DefWindowProcin 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
sizeoffor standard structs (RECT, POINT, WINDOWPLACEMENT).
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 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.