如下以下c程序1.c 运行一段JS脚本
#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脚本函数的。
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv);#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代码编译也字节码

/* 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 );
待完成的开发和测试
通过魔改quickjs,使得VFP能够调用JavaScript脚本,能够修改、新建、删除JavaScript运行时里面的东西,并能够为VFP所用。
拥抱JS,VFP可以拥有更多的未来。比如Web3,AI,机器学习等等。
有人问至于VFP还能学啥,学猫框加入VFP狐友会,你将拥有最黑的VFP科技。