call back to LCB from C code?
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
call back to LCB from C code?
I was wondering if the C code dylib can call back into the LCB?
Re: call back to LCB from C code?
I really don't know enough about LCB (few here do...)Emily-Elizabeth wrote: ↑Sun Mar 08, 2026 8:09 pmI was wondering if the C code dylib can call back into the LCB?
According to Claude:
Claude AI wrote:Yes, C code in a dylib can call back into LCB, through handler references passed as function pointers.
The mechanism works like this:
On the LCB side, you declare a handler type that matches the C callback signature, then pass an LCB handler as a parameter to the foreign function:Key points to be aware of:Code: Select all
-- Declare the callback signature handler type MyCallbackType(in pValue as Integer) returns nothing -- Declare the foreign function that accepts a callback foreign handler C_DoSomethingWithCallback(in pCallback as MyCallbackType) \ returns nothing \ binds to "c:mylib>DoSomethingWithCallback" -- Your LCB handler that will be called from C handler MyCallback(in pValue as Integer) -- this runs when C calls back log pValue end handler -- Wire it up public handler CallIntoC() C_DoSomethingWithCallback(MyCallback) end handler On the C side, the dylib receives a plain function pointer it can invoke normally: ctypedef void (*MyCallbackType)(int value); void DoSomethingWithCallback(MyCallbackType callback) { // Do some work... callback(42); // calls back into LCB }
The LCB handler you pass must match the handler type signature exactly
The callback happens synchronously on the same thread — be cautious if your C code calls back from a different thread, as LCB is not thread-safe in that context
If you need asynchronous callbacks (e.g. from a C thread), you'll need to marshal the call back to the main thread, typically by posting a message or using a queue mechanism, which gets considerably more involved
Memory management: the LCB runtime keeps the handler alive as long as the reference exists, but if C holds onto the pointer longer than the LCB side expects, you can get dangling pointer issues
Re: call back to LCB from C code?
Claude AI wrote: Async callbacks are the tricky case because you cannot call the LCB handler directly from a C thread — it will crash or corrupt state. You need to marshal the call back onto LCB's main thread.
There are two practical approaches:
Option 1: Polling (Simpler)
C side maintains a thread-safe queue. LCB polls it on a timer.
C side:Code: Select all
#include <pthread.h> #include <stdlib.h> // Thread-safe queue static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; static int s_pending_value = 0; static int s_has_pending = 0; // Called from background thread void WorkerThread(void *arg) { // ... do async work ... int result = 42; pthread_mutex_lock(&s_mutex); s_pending_value = result; s_has_pending = 1; pthread_mutex_unlock(&s_mutex); } // LCB calls this on its timer to drain the queue int PollForResult(int *out_value) { pthread_mutex_lock(&s_mutex); int has = s_has_pending; if (has) { *out_value = s_pending_value; s_has_pending = 0; } pthread_mutex_unlock(&s_mutex); return has; }
LCB side:Code: Select all
foreign handler C_PollForResult(out pValue as Integer) \ returns Integer \ binds to "c:mylib>PollForResult" handler type MyCallbackType(in pValue as Integer) returns nothing private variable mCallback as optional MyCallbackType private variable mTimer as optional Timer public handler StartAsync(in pCallback as MyCallbackType) put pCallback into mCallback -- poll every 50ms create timer set the period of the result to 50 set the action of the result to MyPollHandler put the result into mTimer end handler handler MyPollHandler() variable tValue as Integer if C_PollForResult(tValue) is 1 then if mCallback is not nothing then mCallback(tValue) end if end if end handler
Option 2: MCEngineRunloopScheduleCallback (Cleaner)
The LC engine exposes a function that lets C schedule work onto the main thread's runloop — no polling needed.
C side:Code: Select all
// Declare the engine's scheduling function // (available when loaded inside the LC engine process) typedef void (*MCEngineRunloopCallback)(void *context); extern void MCEngineRunloopScheduleCallback( MCEngineRunloopCallback callback, void *context); typedef void (*LCBHandlerType)(int value); typedef struct { LCBHandlerType lcb_handler; int value; } CallbackContext; // Called on main thread by the engine runloop static void MainThreadCallback(void *context) { CallbackContext *ctx = (CallbackContext *)context; ctx->lcb_handler(ctx->value); // safe — we're on main thread now free(ctx); } // Called from background thread void WorkerThread(void *arg) { LCBHandlerType handler = (LCBHandlerType)arg; // ... do async work ... int result = 42; CallbackContext *ctx = malloc(sizeof(CallbackContext)); ctx->lcb_handler = handler; ctx->value = result; // Marshal back to main thread MCEngineRunloopScheduleCallback(MainThreadCallback, ctx); }
LCB side:Code: Select all
handler type MyCallbackType(in pValue as Integer) returns nothing foreign handler C_StartWorker(in pCallback as MyCallbackType) \ returns nothing \ binds to "c:mylib>StartWorker" public handler StartAsync(in pCallback as MyCallbackType) C_StartWorker(pCallback) -- no timer needed; engine calls back when ready end handler
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
Re: call back to LCB from C code?
I'm still learning, but have a few extensions on my website.
Re: call back to LCB from C code?
Dear Emily-Elizabeth,
thank you very much for all of your work, much appreciated!
Looking forward to whatever you will create in the future.
Best
Klaus
P.S.
Does .nf stand for Norfolk Island, south of Australia?
thank you very much for all of your work, much appreciated!
Looking forward to whatever you will create in the future.
Best
Klaus
P.S.
Does .nf stand for Norfolk Island, south of Australia?
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
Re: call back to LCB from C code?
Thank you for the kind words. Check out my website for a few goodies that I've already made (just rename the oxtstack to livecodestack).
Seems like it is.NF is the extension code for Norfolk Island.
Re: call back to LCB from C code?
Dear Emily-Elizabeth,
of course I already check your site, nice stuff.
Canada not Norfolk Island, OK, get it!
Best
Klaus
of course I already check your site, nice stuff.
Canada not Norfolk Island, OK, get it!
Best
Klaus
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
Re: call back to LCB from C code?
Aren't you full of kind words this morning
Yeah, the cold and icy place
Re: call back to LCB from C code?
I'm always full of kind words, kudos goes to my mom! 
-
Emily-Elizabeth
- Posts: 157
- Joined: Mon Jan 03, 2022 7:10 pm
- Contact:
Re: call back to LCB from C code?
aww.. Moms are awesome