首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >quickjs传参并调用JS函数,VFP黑科技

quickjs传参并调用JS函数,VFP黑科技

作者头像
加菲猫的VFP
发布2023-10-06 14:30:07
发布2023-10-06 14:30:07
1.8K0
举报
文章被收录于专栏:加菲猫的VFP加菲猫的VFP

如下以下c程序1.c 运行一段JS脚本

代码语言:javascript
复制
#include <stdio.h>
#include "quickjs-libc.h"
#include <string.h>

int main(int argc, char **argv)
{
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
js_std_add_helpers(ctx, 0, NULL);

const char *scripts = "console.log('hello quickjs')";
JS_Eval(ctx, scripts, strlen(scripts), "main", 0);
}

然后编译成1.exe

运行成功。

现在再来看这个C函数,是可以调用JS脚本函数的。

代码语言:javascript
复制
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
                int argc, JSValueConst *argv);
代码语言:javascript
复制
#include <stdio.h>
#include "quickjs-libc.h"
#include <string.h>

int main(int argc, char **argv)
{

JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
js_std_add_helpers(ctx, 0, NULL);
 const char *scripts = R"(
 function calculate(ttt){
            return ttt+2000;
        }
     console.log('I is JS CODE ');
    console.log(calculate(1));
    console.log('hello,quickJS!'))";

   JS_Eval(ctx, scripts, strlen(scripts), "main", 0);  //加载JS代码
   //函数绑定   JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv);
   //准备调用参数
    JSValue dNum1 = JS_NewFloat64(ctx,99);
    JS_FreeValue(ctx,dNum1 );
 
    JSValue jsObject = JS_GetGlobalObject(ctx);
    JSValue jsCalculate = JS_GetPropertyStr(ctx,jsObject ,"calculate");  //找出要调用的函数

    JS_FreeValue(ctx,jsObject);
    JS_FreeValue(ctx, jsCalculate);
    //正式调用 
    JSValue jsResult= JS_Call(ctx,jsCalculate,JS_UNDEFINED,1,(JSValueConst *)&dNum1);
   // JS_Call 应该返回的是字符串,所以用字符串来输出结果。
    printf("I is C code----%s",JS_ToCString(ctx,jsResult));
    JS_FreeValue(ctx, jsResult); 

     js_std_loop(ctx);
    JS_FreeContext(ctx);
    JS_FreeRuntime(rt);

}

直接调用字节码也是可以的。

可以看到,JS 里面调用函数也是有输出的,下面的C也调用成功并且传参了。

现在加载的是JS源码,那么加载字符串是不是也可以。

将如上js代码编译也字节码

代码语言:javascript
复制
/* File generated automatically by the QuickJS compiler. */

#include "quickjs-libc.h"

const uint32_t qjsc_5_1_size = 197;

const uint8_t qjsc_5_1[197] = {
 0x02, 0x07, 0x12, 0x63, 0x61, 0x6c, 0x63, 0x75,
 0x6c, 0x61, 0x74, 0x65, 0x0e, 0x63, 0x6f, 0x6e,
 0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67,
 0x1a, 0x49, 0x20, 0x69, 0x73, 0x20, 0x4a, 0x53,
 0x20, 0x43, 0x4f, 0x44, 0x45, 0x20, 0x1c, 0x68,
 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x71, 0x75, 0x69,
 0x63, 0x6b, 0x4a, 0x53, 0x21, 0x0c, 0x35, 0x2e,
 0x31, 0x2e, 0x6a, 0x73, 0x06, 0x74, 0x74, 0x74,
 0x0e, 0x00, 0x06, 0x00, 0xa0, 0x01, 0x00, 0x01,
 0x00, 0x04, 0x00, 0x01, 0x4a, 0x01, 0xa2, 0x01,
 0x00, 0x00, 0x00, 0x3f, 0xe1, 0x00, 0x00, 0x00,
 0x40, 0xc0, 0x00, 0x40, 0xe1, 0x00, 0x00, 0x00,
 0x00, 0x38, 0xe2, 0x00, 0x00, 0x00, 0x42, 0xe3,
 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00,
 0x24, 0x01, 0x00, 0xc9, 0x38, 0xe2, 0x00, 0x00,
 0x00, 0x42, 0xe3, 0x00, 0x00, 0x00, 0x38, 0xe1,
 0x00, 0x00, 0x00, 0xb6, 0xef, 0x24, 0x01, 0x00,
 0xc9, 0x38, 0xe2, 0x00, 0x00, 0x00, 0x42, 0xe3,
 0x00, 0x00, 0x00, 0x04, 0xe5, 0x00, 0x00, 0x00,
 0x24, 0x01, 0x00, 0xcd, 0x28, 0xcc, 0x03, 0x01,
 0x06, 0x1f, 0x00, 0x08, 0x08, 0x62, 0x6c, 0x0e,
 0x43, 0x06, 0x00, 0xc2, 0x03, 0x01, 0x00, 0x01,
 0x02, 0x00, 0x00, 0x06, 0x01, 0xce, 0x03, 0x00,
 0x01, 0x00, 0xd1, 0xbe, 0xd0, 0x07, 0x9d, 0x28,
 0xcc, 0x03, 0x01, 0x01, 0x03,
};


int main(int argc, char **argv)
{

JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
js_std_add_helpers(ctx, 0, NULL);
     js_std_eval_binary(ctx, qjsc_5_1, qjsc_5_1_size, 0);  //加载二进制
   //JS_Eval(ctx, scripts, strlen(scripts), "main", 0);  //加载JS代码

   //函数绑定   JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv);
   //准备调用参数
    JSValue dNum1 = JS_NewFloat64(ctx,99);
    JS_FreeValue(ctx,dNum1 );
 
    JSValue jsObject = JS_GetGlobalObject(ctx);
    JSValue jsCalculate = JS_GetPropertyStr(ctx,jsObject ,"calculate");  //找出要调用的函数

    JS_FreeValue(ctx,jsObject);
    JS_FreeValue(ctx, jsCalculate);
    //正式调用 
    JSValue jsResult= JS_Call(ctx,jsCalculate,JS_UNDEFINED,1,(JSValueConst *)&dNum1);
   // JS_Call 应该返回的是字符串,所以用字符串来输出结果。 
    printf("I is C code----%s",JS_ToCString(ctx,jsResult));
    JS_FreeValue(ctx, jsResult); 

     js_std_loop(ctx);
    JS_FreeContext(ctx);
    JS_FreeRuntime(rt);

}

也同样执行成功。

JS

JS_Eval(ctx,scripts,strlen(scripts),"eval",0); //加载执行JS源码

js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0); //加载执行二进制

//找出要调用的函数

JSValue jsObject = JS_GetGlobalObject(ctx);

JSValue jsCalculate = JS_GetPropertyStr(ctx,jsObject ,"calculate");

传参并执行JS函数

JSValue jsResult= JS_Call(ctx,jsCalculate,JS_UNDEFINED,1,(JSValueConst *) &dNum1 );

待完成的开发和测试

  1. 实现在 main.c 里面调用js函数 (完成)
  2. 实现把c程序编译成dll,让VFP调用 (完成)
  3. 把JS引擎放进dll,可使用Quickjs引擎,ES2015标准
  4. 把运行时txiki.js入进dll中,可完整使用JS运行时的各项功能
  5. 完整整合JS引擎和JS运行时

通过魔改quickjs,使得VFP能够调用JavaScript脚本,能够修改、新建、删除JavaScript运行时里面的东西,并能够为VFP所用。

拥抱JS,VFP可以拥有更多的未来。比如Web3,AI,机器学习等等。

有人问至于VFP还能学啥,学猫框加入VFP狐友会,你将拥有最黑的VFP科技。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-10-04 10:34,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲猫的VFP 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档