Windows下编译quickjs

Windows下编译quickjs

第一步:安装msys

msys官网
安装后配置镜像源镜像源地址及配置方式
之后打开msys2 ucrt64并安装如下工具

pacman -S mingw-w64-ucrt-x86_64-gcc
pacman -S mingw-w64-ucrt-x86_64-toolchain
pacman -S mingw-w64-ucrt-x86_64-dlfcn
pacman -S make

第二步:修改代码

打开quickjs-libc.c文件,找到js_module_loader函数
修改一行函数

if (has_suffix(module_name, ".so")|| has_suffix(module_name, ".dll")) {//添加部分为|| has_suffix(module_name, ".dll")

之后修改:#if defined(_WIN32)宏定义下的js_module_loader_so函数

static JSModuleDef *js_module_loader_so(JSContext *ctx,
                                        const char *module_name)
{
    JSModuleDef *m;
    void *hd;
    JSInitModuleFunc *init;
    char *filename;

    if (!strchr(module_name, '/')) {
        /* must add a '/' so that the DLL is not searched in the
           system library paths */
        filename = js_malloc(ctx, strlen(module_name) + 2 + 1);
        if (!filename)
            return NULL;
        strcpy(filename, "./");
        strcpy(filename + 2, module_name);
    } else {
        filename = (char *)module_name;
    }

    /* C module */
    hd = LoadLibrary(filename);//dlopen修改为LoadLibrary
    if (filename != module_name)
        js_free(ctx, filename);
    if (!hd) {
        JS_ThrowReferenceError(ctx, "could not load module filename '%s' as shared library",
                               module_name);
        goto fail;
    }

    init = (JSInitModuleFunc*)GetProcAddress(hd, "js_init_module");//dlsym修改为GetProcAddress
    if (!init) {
        JS_ThrowReferenceError(ctx, "could not load module filename '%s': js_init_module not found",
                               module_name);
        goto fail;
    }

    m = init(ctx, module_name);
    if (!m) {
        JS_ThrowReferenceError(ctx, "could not load module filename '%s': initialization error",
                               module_name);
    fail:
        if (hd)
            FreeLibrary(hd);//dlclose修改为FreeLibrary
        return NULL;
    }
    return m;
}

之后,修改Makefile文件,取消
CONFIG_WIN32=y的注释,
并添加生成def文件的命令,三组代码根据makefile的内容排布自行插入

DEF_FILE = libquickjs.def

PROGS+=$(DEF_FILE)

$(DEF_FILE): $(QJS_LIB_OBJS)
	@echo "EXPORTS" > $(DEF_FILE)
	@nm $(QJS_LIB_OBJS) | grep ' T ' | awk '{print $$3}' >> $(DEF_FILE)

第三步:编译生成

生成静态库.a,可执行文件
 make LDEXPORT="-static -s"  
 生成动态库dll
  gcc -shared -o libquickjs.dll -static -s -Wl,--whole-archive libquickjs.a -lm -Wl,--no-whole-archive
 

之后,打开visualstudio的工具x64 native tools
在这里插入图片描述
定位到def文件生成路径下,输入 lib /DEF:libquickjs.def,得到lib文件
在这里插入图片描述

第四步:测试使用

将之前生成的lib与dll库复制到项目的目录与可执行文件的目录下,由于quickj代码有警告
所以可以在自己项目的顶部使用:#pragma warning(disable:4576)
或者在cmakelists中添加:add_compile_options(/wd4576)#禁用4576警告

//测试代码
//#pragma warning(disable:4576)
#include <iostream>
#include "quickjs-libc.h"
int main(int argc, char** argv)
{
    //运行时
    JSRuntime* rt = JS_NewRuntime();
    //上下文
    JSContext* ctx = JS_NewContext(rt);
    std::string jsCode = R"(
        function calculate(num1, num2, operator){
            switch(operator){
                case '+':
                    return num1 + num2;
                case '-':
                    return num1 - num2;
            }
        }
    )";

    JSValue jsRes = JS_Eval(ctx, jsCode.c_str(), jsCode.length(), "<evalScript>", JS_EVAL_TYPE_GLOBAL);
    if (JS_IsException(jsRes))
    {
        js_std_dump_error(ctx);
        return 0;
    }
    JS_FreeValue(ctx, jsRes);
    //参数设置
    double dNum1 = 10, dNum2 = 20;
    std::string strOperator = "+";
    JSValue arg[3];
    arg[0] = JS_NewFloat64(ctx, dNum1);
    arg[1] = JS_NewFloat64(ctx, dNum2);
    arg[2] = JS_NewString(ctx, strOperator.c_str());
    //函数绑定
    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, 3, (JSValueConst*)arg);
    if (JS_IsException(jsResult))
    {
        js_std_dump_error(ctx);
        return 0;
    }

    //释放资源
    JS_FreeValue(ctx, arg[2]);
    JS_FreeValue(ctx, arg[1]);
    JS_FreeValue(ctx, arg[0]);
    double dValue;
    if (JS_ToFloat64(ctx, &dValue, jsResult))
    {
        std::cout << " Call error " << std::endl;
        JS_FreeContext(ctx);
        JS_FreeRuntime(rt);
        return 0;
    }
    JS_FreeValue(ctx, jsResult);
    std::cout << "calculate " << dNum1 << " " << strOperator << " " << dNum2 << " = " << dValue << std::endl;
    JS_FreeContext(ctx);
    JS_FreeRuntime(rt);
    return 0;
}

https://zhuanlan.zhihu.com/p/623863082
https://blog.csdn.net/slaltum/article/details/133142451
https://blog.csdn.net/yunfeiyang62/article/details/45949701
https://blog.csdn.net/w371584831/article/details/129025300

经常看到有人要找AES-GCM-128  这个算法加解密 网上相关的文档也较少其中在telegram登录首页就在使用该算法 应该让不少哥们头疼 其实这个加密常见于浏览器内置接口window.crypto.subtle 该接口不仅支持该类型的加密 且支持非常多的算法加密如RSA DES  等等  这里就演示AES-GCM-128 这个类型 crypto-AES-GCM-128调用例子 function ___crypto__test(keyData, iv, data) {     const format = "raw",         // keyData = new Uint8Array([23, 113, 57, 6, 35, -69, -60, 98, 84, -17, -125, -49, 18, 6, -92, 32]),         algorithm = "AES-GCM",         extractable = true,         usages = ["encrypt", "decrypt"];     // iv = new Uint8Array([47, 46, 123, 78, 36, 14, 109, 50, 121, 64, 11, 38]);     window.crypto.subtle.importKey(         format,         keyData,         algorithm,         extractable, usages     ).then(key =gt; {         window.crypto.subtle.encrypt({                 name: algorithm,                 iv: iv             },             key,             data         ).then(result =gt; {             console.log(Array.from(new Uint8Array((result))))         })     }) } console.log(___crypto__test(             new Uint8Array([23, 113, 57, 6, 35, -69, -60, 98, 84, -17, -125, -49, 18, 6, -92, 32]),                 new Uint8Array([47, 46, 123, 78, 36, 14, 109, 50, 121, 64, 11, 38]),             new Uint8Array([50, 49, 48]) )) crypto主要相关接口介绍 crypto.subtle.importKey const result = crypto.subtle.importKey(     format,     keyData,     algorithm,     extractable,     usages ); format  是一个字符串,描述要导入的密钥的数据格式。可以是以下之一:----------raw:原始格式。----------pkcs8:PKCS#8格式。----------spki:SubjectPublicKeyInfo格式。----------jwk:JSON Web密钥格式。 - keyData 是ArrayBuffer,TypedArray,a DataView或JSONWebKey包含给定格式的键的对象。 - algorithm  是一个字典对象,用于定义要导入的密钥的类型并提供额外的算法特定参数。对于RSASSA-PKCS1-v1_5,  RSA-PSS或  RSA-OAEP:传递RsaHashedImportParams对象。对于ECDSA或ECDH:传递  EcKeyImportParams对象。对于HMAC:传递一个HmacImportParams对象。对于AES-CTR,AES-CBC,AES-GCM或AES-KW:传递标识算法的字符串或形式为的对象{ "name": ALGORITHM },其中ALGORITHM 是算法的名称。对于PBKDF2  :传递字符串PBKDF2。 - extractable 是Boolean表明它是否将有可能使用到导出密钥SubtleCrypto.exportKey()或SubtleCrypto.wrapKey()。 - ke
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值