首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用QuickJS修改首选项和全局变量

使用QuickJS修改首选项和全局变量
EN

Stack Overflow用户
提问于 2021-11-26 11:23:50
回答 1查看 347关注 0票数 1

我感兴趣的是使用QuickJS修改C++应用程序中的首选项。因此,有一个名为int myPref = 0的首选项变量

我想将它公开为一个名为jsPref的JS变量。

然后,用户可以使用jsPref = 1通过JS直接修改它。

这可以扩展到一个结构,在这个结构中,可以定义struct myPref { int a, int b};,它在JS中公开为jsPref

在JS脚本中,我想调用

代码语言:javascript
复制
jsPref.a = 1;
jsPref.b = 2;

而且赋值应该反映在C结构myPref中--很遗憾,我甚至没有公开一个结构的示例代码。在搜索之后,我只想出了一些C/C++函数作为JS方法公开的例子。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-28 18:07:40

看看例如JS_AddIntrinsicAtomics源代码中的QuickJS。它使用JS_SetPropertyFunctionList创建一个对象,其属性由一个简单的结构数组定义,并借助一些方便的宏。

JS_CFUNC_MAGIC_DEF不同,您可以使用JS_CGETSET_DEFJS_CGETSET_MAGIC_DEF来使用getter和setter定义自定义属性。由于JSContext结构的内容没有在公共API中公开,所以您必须使用JS_GetGlobalObject来访问全局对象。否则,你需要做的基本上是一样的。

这个应该是这样的:

代码语言:javascript
复制
// those will be called when jsPref.a is accessed
static JSValue pref_a_get(JSContext *ctx, JSValueConst this_val);
static JSValue pref_a_set(JSContext *ctx, JSValueConst this_val, JSValueConst value);

// those will be called when jsPref.b or jsPref.c is accessed and receive 123 or 456 respectively in the `magic` parameter
static JSValue pref_bc_get(JSContext *ctx, JSValueConst this_val, int magic);
static JSValue pref_bc_set(JSContext *ctx, JSValueConst this_val, JSValueConst value, int magic);

static const JSCFunctionListEntry prefs_obj_props[] = {
    JS_CGETSET_DEF("a", pref_a_get, pref_a_set),
    JS_CGETSET_MAGIC_DEF("b", pref_bc_get, pref_bc_set, 123),
    JS_CGETSET_MAGIC_DEF("c", pref_bc_get, pref_bc_set, 456),
};

static const JSCFunctionListEntry prefs_obj[] = {
    JS_OBJECT_DEF("jsPref", prefs_obj_props, countof(prefs_obj_props), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ),
};

void create_prefs_obj(JSContext *ctx)
{
    JSValue globalThis = JS_GetGlobalObject(ctx);
    JS_SetPropertyFunctionList(ctx, globalThis, prefs_obj, countof(prefs_obj));
    JS_FreeValue(ctx, globalThis);
}

以上定义了结构的变化。对于单个首选项,可以将JS_CGETSET_DEF定义直接放在prefs_obj中,以定义全局对象的基于访问器的属性。

请注意,使用JS_CGETSET_DEF定义的属性是可配置的,这意味着用户代码可以执行例如delete jsPrefs.a;并失去对公开属性的访问。如果要防止这种情况发生,则必须编写自己的助手宏,以便自己设置属性标志。您还可能希望查看JS_PreventExtensions,以捕获试图写入不存在的首选项的用户代码。如果您想使用它,您可能需要用JS_NewObject创建preferences对象,用JS_SetPropertyFunctionList定义它的属性,封住它,然后用JS_DefinePropertyValue手动地将它添加到全局对象中,而不是使用一个JS_SetPropertyFunctionList调用一次完成所有操作:

代码语言:javascript
复制
void create_prefs_obj(JSContext *ctx)
{
    JSValue globalThis = JS_GetGlobalObject(ctx);

    // null prototype to avoid namespace clashes
    JSValue prefsObj = JS_NewObjectProto(ctx, JS_NULL);

    // define preference properties
    JS_SetPropertyFunctionList(ctx, prefsObj, prefs_obj, countof(prefs_obj));

    // catch user code writing to nonexistent properties
    JS_PreventExtensions(ctx, prefsObj);

    // expose the preferences object
    JS_DefinePropertyValueStr(ctx, globalThis, "jsPref", prefsObj, PROP_CONFIGURABLE | PROP_WRITABLE);
    JS_FreeValue(ctx, globalThis);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70123636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档