1

so I've had a look online and can't really find much. I was hoping someone might have experience setting up a .registerCallback() method in an embedded quickjs project.

the type of use would be like this in the script:

import {Class} from 'Class'
let c = new Class();
c.registerCallback(callbackfunc);

function callbackfunc() {}

the addCallbackMethod in the cpp file:

// Custom method function: Performs a custom operation on the object
static JSValue myClass_addCallbackMethod(
    JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
    auto* object = static_cast<myClassData *>(
        JS_GetOpaque2(ctx, this_val, myClassId));

    // If no callback function is provided or the provided argument is not a function, return an exception
    if (argc == 0 || !JS_IsFunction(ctx, argv[0]))
        return JS_ThrowTypeError(ctx, "Expected a function as argument");

    // Store the callback function in the object
    object->registeredCallback = JS_DupValue(ctx, argv[0]);

    return JS_UNDEFINED;
}

I've had a go and I thought I was on the right track but it seems to give me seg faults whenever I try and access the object's property that's holding the function in my main.cpp

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
sh93
  • 11
  • 2

2 Answers2

0
// Define the callback function
static JSValue myCallback(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    // Handle the callback logic here
    // ...
    return JS_UNDEFINED;
}

// Create a C function that serves as a wrapper for the callback function
static JSValue js_myCallback(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    return myCallback(ctx, this_val, argc, argv);
}

// Register the callback function in your QuickJS runtime
JSValue global_obj = JS_GetGlobalObject(ctx);
JS_SetPropertyStr(ctx, global_obj, "myCallback", JS_NewCFunction(ctx, js_myCallback, "myCallback", 0));
JS_FreeValue(ctx, global_obj);

This code assumes you have a QuickJS context ctx where you want to register the callback function. It defines the callback function myCallback and a wrapper function js_myCallback that calls the callback function. Then, it registers the callback function by assigning it to a property named "myCallback" on the global object.

Remember to include the appropriate QuickJS headers and link against the QuickJS library when compiling your embedded project.

  • 1
    i think the problem with both of these suggestions is that it assumes the script is being evaluated globally. i'm a bit confused on how to handle the scope – sh93 May 17 '23 at 21:04
0
void my_callback(JSContext *ctx, JSValueConst value) {
  // Do something with the value.
}

int main() {
  // Create a QuickJS context.
  JSContext *ctx = js_new_context();

  // Register the callback function.
  js_add_global_function(ctx, "my_callback", my_callback, 0);

  // Evaluate a JavaScript string.
  js_eval(ctx, "my_callback(123);");

  // Dispose of the context.
  js_free_context(ctx);

  return 0;
}
  1. The first line includes the quickjs.h header file, which contains the declarations for the QuickJS API.
  2. The second line defines a function called my_callback. This function will be called when the JavaScript string my_callback(123); is evaluated. The function takes one argument, which is the value of the expression 123.
  3. The third line calls the js_new_context() function to create a new QuickJS context.
  4. The fourth line calls the js_add_global_function() function to register the my_callback function with the context. The fifth line calls the js_eval() function to evaluate the JavaScript string my_callback(123);. The sixth line calls the js_free_context() function to dispose of the context. The seventh line returns 0 to indicate that the program exited successfully.
Saptadeep
  • 1
  • 1