首页 > 其他分享 >quickjs C功能扩展的四种写法

quickjs C功能扩展的四种写法

时间:2023-12-14 19:33:07浏览次数:24  
标签:quickjs ctx JS jl print js 写法 class 四种

一、前言

   茴香豆的“茴”字有多少种写法?这篇博客不是为了炫技,是JS就是这么多种情况。比如C语言,就只能通过函数调用,没有类的概念。比如Java,就只能通过类、对象的方式。不能单独创建函数。哪怕main函数也要包装成一个class。而JS,即可以提供函数,也可以提供类。

  在ES5之前,JS还没有模块的概念,现在用的quickjs已经支持模块引用。我看其他人用JerryScript之类的,虽然不支持模块引用,但是可以通过Babel、tsc之类的,解决低版本js引擎对新语法的支持。

二、以完整模块导出函数、属性

  绑定

 

 1 static JSValue JLJS_Print(JSContext *ctx, JSValueConst this_val,
 2                               int argc, JSValueConst *argv)
 3 {
 4   const char *str;
 5   if(argc > 0){
 6     str = JS_ToCString(ctx, argv[0]);
 7   }
 8   printf("->%s\n", str);
 9   JS_FreeCString(ctx, str);
10 }
11 static const JSCFunctionListEntry jl_js_print_funcs[] = {
12     JS_CFUNC_DEF("Print", 1, JLJS_Print)
13 };
14 static int jl_js_print_init(JSContext *ctx, JSModuleDef *m)
15 {
16   return JS_SetModuleExportList(ctx, m, jl_js_print_funcs, countof(jl_js_print_funcs));
17 }
18 JSModuleDef* jl_js_init_module_print(JSContext *ctx, const char *module_name)
19 {
20   JSModuleDef * m = JS_NewCModule(ctx, module_name, jl_js_print_init);
21   if(!m)
22   {
23     return NULL;
24   }
25   JS_AddModuleExportList(ctx, m, jl_js_print_funcs, countof(jl_js_print_funcs));
26   return m;
27 }

 

  注册

 

1 jl_js_init_module_print(qrt->ctx, "m");

 

  调用

 

1 import * as m from 'm';
2 m.Print('hello world');
3 
4 import {Print} from 'm';
5 Print('hello world');

 

 

 

三、以属性形式导出函数、属性

  绑定

 

1 static const JSCFunctionListEntry jl_js_m_print_funcs[] = {
2     JS_OBJECT_DEF("m", jl_js_print_funcs, countof(jl_js_print_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)
3 };
4 void jl_js_init_register(JSContext* ctx, JSValue global)
5 {
6   JSValue obj = JS_NewObjectProto(ctx, JS_NULL);
7   JS_SetPropertyFunctionList(ctx, obj, jl_js_m_print_funcs, countof(jl_js_m_print_funcs));
8   JS_DefinePropertyValueStr(ctx, global, "reg", obj, JS_PROP_C_W_E);
9 }

 

  注册

 

1 JSValue global_obj = JS_GetGlobalObject(qrt->ctx);
2 jl_js_init_register(qrt->ctx, global_obj);

 

  调用

 

1 reg.m.Print('reg.m.Print');

 

 

 

四、以完整模块导出类、对象

  绑定

 

 1 typedef struct{
 2   int val;
 3 } PrintClass;
 4 static JSClassID print_class_id;
 5 static void JLJS_CLASS_PrintFinalize(JSRuntime *rt, JSValue val)
 6 {
 7   PrintClass *cls = (PrintClass *)JS_GetOpaque(val, print_class_id);
 8   if(cls){
 9     js_free_rt(rt, cls);
10   }
11 }
12 static JSClassDef print_class_def = {
13   .class_name = "Print",
14   .finalizer = JLJS_CLASS_PrintFinalize, // 析构函数
15   .gc_mark = NULL
16 };
17 //构造函数
18 static JSValue JLJS_CLASS_PrintConstructor(JSContext *ctx, JSValueConst new_target,
19                                        int argc, JSValueConst *argv)
20 {
21   JSValue obj = JS_UNDEFINED;
22   PrintClass *cls = (PrintClass *)js_malloc(ctx, sizeof(PrintClass));
23   if(argc > 0){
24     JS_ToInt32(ctx, &cls->val, argv[0]);
25     JSValue val = JS_DupValue(ctx, argv[0]);
26   }
27   JSValue proto = JS_GetPropertyStr(ctx, new_target, "prototype");
28   obj = JS_NewObjectProtoClass(ctx, JS_NULL/*proto*/, print_class_id);
29   JS_SetPrototype(ctx, obj, proto);
30   JS_FreeValue(ctx, proto);
31   JS_SetOpaque(obj, cls);
32   return obj;
33 }
34 static JSValue JLJS_CLASS_PrintTestFunc(JSContext *ctx, JSValueConst this_val,
35                                        int argc, JSValueConst *argv)
36 {
37   PrintClass * cls = (PrintClass *) JS_GetOpaque2(ctx, this_val, print_class_id);
38   if(cls == NULL){
39     return JS_EXCEPTION;
40   }
41   if(argc > 0){
42     JS_ToInt32(ctx, &cls->val, argv[0]);
43   }
44   printf("Print Value: %d\n", cls->val);
45 }
46 static JSValue jl_js_print_class_get_val(JSContext *ctx, JSValueConst this_val)
47 {
48   PrintClass * cls = (PrintClass *) JS_GetOpaque2(ctx, this_val, print_class_id);
49   if(cls == NULL){
50     return JS_EXCEPTION;
51   }
52   return JS_NewInt32(ctx, cls->val);
53 }
54 static JSValue jl_js_print_class_set_val(JSContext *ctx, JSValueConst this_val, JSValueConst val)
55 {
56   PrintClass * cls = (PrintClass *) JS_GetOpaque2(ctx, this_val, print_class_id);
57   if(cls == NULL){
58     return JS_EXCEPTION;
59   }
60   JS_ToInt32(ctx, &cls->val, val);
61   return JS_UNDEFINED;
62 }
63 static const JSCFunctionListEntry jl_js_print_class_funcs[] = {
64     JS_CFUNC_DEF("PrintTestFunc", 1, JLJS_CLASS_PrintTestFunc),
65     // JS_PROP_INT32_DEF("val", 1, JS_PROP_C_W_E)
66     JS_CGETSET_DEF("val", jl_js_print_class_get_val, jl_js_print_class_set_val)
67 };
68 void jl_js_init_print_class_module(JSContext* ctx, JSModuleDef *m)
69 {
70   JS_NewClassID(&print_class_id);
71   JS_NewClass(JS_GetRuntime(ctx), print_class_id, &print_class_def);
72   JSValue proto = JS_NewObject(ctx);
73   JS_SetPropertyFunctionList(ctx, proto, jl_js_print_class_funcs, countof(jl_js_print_class_funcs));
74 
75   JSValue ctor = JS_NewCFunction2(ctx, JLJS_CLASS_PrintConstructor, print_class_def.class_name, 1, JS_CFUNC_constructor, 0);
76   JS_SetConstructor(ctx, ctor, proto); //给proto设置一个构造函数ctor
77   JS_SetClassProto(ctx, print_class_id, proto); //为print这个类,设置原型链
78   JS_SetModuleExport(ctx, m, print_class_def.class_name, ctor);//设置可导出类 只导出构造函数
79 }
80 int jl_js_init_class_module_list(JSContext *ctx, JSModuleDef *m)
81 {
82   jl_js_init_print_class_module(ctx, m);
83   //其他class初始化
84   return 0;
85 }
86 JSModuleDef* jl_js_init_class_module(JSContext *ctx, const char *module_name)
87 {
88   JSModuleDef * m = JS_NewCModule(ctx, module_name, jl_js_init_class_module_list);
89   if(!m)
90   {
91     return NULL;
92   }
93   //导出类名,注意这里与上面的JS_SetModuleExport对应
94   JS_AddModuleExport(ctx, m, print_class_def.class_name);
95   return m;
96 }

 

  注册

 

1 jl_js_init_class_module(qrt->ctx, "_G");

 

  调用

 

 1 import * as _G from '_G'
 2 var g = new _G.Print(1);
 3 g.val = 3;
 4 g.PrintTestFunc();
 5 g.PrintTestFunc(10);
 6 
 7 import {Print} from '_G';
 8 var g = new Print(1);
 9 g.val = 3;
10 g.PrintTestFunc();
11 g.PrintTestFunc(10);

 

 

 

五、以属性形式导出类、对象

  绑定

 

 1 void jl_js_init_class_register(JSContext *ctx, JSValue global)
 2 {
 3   JS_NewClassID(&print_class_id);
 4   JS_NewClass(JS_GetRuntime(ctx), print_class_id, &print_class_def);
 5   JSValue proto = JS_NewObjectProto(ctx, JS_NULL);
 6   JS_SetPropertyFunctionList(ctx, proto, jl_js_print_class_funcs, countof(jl_js_print_class_funcs));
 7 
 8   JSValue ctor = JS_NewCFunction2(ctx, JLJS_CLASS_PrintConstructor, print_class_def.class_name, 1, JS_CFUNC_constructor, 0);
 9   JS_SetConstructor(ctx, ctor, proto); //给proto设置一个构造函数ctor
10   JS_SetClassProto(ctx, print_class_id, proto); //为print这个类,设置原型链
11 
12   JS_DefinePropertyValueStr(ctx, global, "Print", ctor, JS_PROP_C_W_E);
13 }

 

  注册

 

1 jl_js_init_class_register(qrt->ctx, global_obj);

 

  调用 

 

1 var pt = new Print(1);
2 pt.val = 3;
3 pt.PrintTestFunc();

 

 

 

本文地址:https://www.cnblogs.com/wunaozai/p/17901642.html

系列目录:https://www.cnblogs.com/wunaozai/p/17853962.html

标签:quickjs,ctx,JS,jl,print,js,写法,class,四种
From: https://www.cnblogs.com/wunaozai/p/17901642.html

相关文章

  • Python各种奇奇怪怪的写法以及常用案例
    工具类common#####工具类commonimportrequestsimporttimeimportjsonimportrandomimportosfromlxmlimportetreeimportconcurrent.futuresfromurllib.parseimportunquote,quotefromPILimportImagedefstrClear_v1(str):try:returnst......
  • Python实现单例模式的五种写法
    单例模式是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点。在Python中,可以使用多种方法实现单例模式。本文将介绍五种常见的Python单例模式实现方式,包括使用模块、装饰器、基类、元类和线程安全机制。单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供全局......
  • quickjs集成http功能
    零、前言默认的quickjs,是js引擎,需要自己移植类似curl库,才能使quickjs有http请求功能。js引擎+一些本地功能调用=js运行时。一、libcurl库这个库的安装或编译,也是比较麻烦的事情,特别是需要使其支持https访问,配置和编译更是麻烦。因此,还是使用上次提到的vcpkg。通过vcpkg......
  • git文件的四种状态
    gitstatus查看文件状态命令命令:gitstatus[<选项>...][]表示可选,...表示可以有很多项,可选参数有:-s精简输出-b显示分支信息-v显示变更的文本内容文件的四种状态Untracked:未跟踪的文件,该文件在文件夹中,但是没有加入到本地仓库,不参与版本控制......
  • mysql中count函数的几种写法解析
    一、count(主键)innodb引擎会遍历整张表,把每一行的主键值都取出来返回给服务层,服务层拿到主键后直接按行进行计数累加二、count(特定字段)2.1没有notnull约束innodb引擎会遍历整张表,把每一行的字段值都取出来返回给服务层,服务层判断是否为null,不为null计数累加2.2有no......
  • Python - 实现【单例模式】的四种方法
    方法一:使用模块实现单例模式在Python中,每个模块只会被导入一次,因此可以将需要实现单例模式的类定义在一个模块中,每次需要使用该类时,将该模块导入即可。#singleton.pyclassSingleton:passsingleton=Singleton()在其他模块中直接引用这个singleton对象即可。2.方法二:使......
  • robots.txt禁止收录协议写法
    1. 什么是robots.txt?robots.txt 是网站和搜索引擎的协议的纯文本文件。当一个搜索引擎蜘蛛来访问站点时,它首先爬行来检查该站点根目录下是否存在robots.txt,如果存在,根据文件内容来确定访问范围,如果没有,蜘蛛就沿着链接抓取。robots.txt 放在项目的根目录下。2. robots.txt......
  • httpclient跳过SSL证书验证的写法
    最近在请求https接口的时候,发生了异常:sun.security.validator.ValidatorException:PKIXpathbuildingfailed:sun.security.provider.certpath.SuncertPathBuilderException:unabletofindvalidcertificationpathtorequestedtarget无法找到到请求目标的有效证书路......
  • 去除数字末尾0正则写法
    letnums=['12.00','12.001','12.100','12.350','12.45'];console.log('nums:',nums);nums.forEach(t=>{console.log('num:',trimZero(t))})functiontrimZero(num){/......
  • quickjs模块封装、类封装
    一、模块封装、类封装通过quickjs,封装JS模块,然后可以通过import导入对应模块,还可以导入具体的类。全部代码如下。1#include"quickjs-libc.h"2#include<stdio.h>3#include<inttypes.h>4#include<string.h>5#include"cutils.h"67staticJSC......