首页 > 编程语言 >认识soui4js(第三篇):使用C/C++开发扩展模块

认识soui4js(第三篇):使用C/C++开发扩展模块

时间:2023-06-21 15:22:47浏览次数:50  
标签:qjsbind 第三篇 context ExportFunc module C++ 模块 Context soui4js

首先需要明确:JS代码本身不具备直接调用系统API的能力,JS代码能调用什么功能,都依赖于其它扩展模块提供了什么样的接口。

soui4js模块将soui的界面能力作为一个js模块导出到了js中,使得js可以和C++一样操作GUI。

但是操作GUI只是一个客户端APP的一个需求。一个产品可能会有各种需求是现有模块不能实现的,或者是能性能要求很高不宜使用JS实现的。

这就需要用户自己使用如C/C++这样的语言来扩展js模块。

soui4js的代码中有一个模块utils,它就是一个典型的扩展模块。

在该模块中,我们导出了几个文件操作,编码转换方法。用户要扩展自己的模块,只需要参考utils模块来增加自己的API即可。

utils模块是一个dll项目,编译后生成一个utils.dll

该dll导出两个方法:

 1 extern "C"
 2 __declspec(dllexport) JSModuleDef* js_init_module(JSContext* ctx, const char* module_name)
 3 {
 4     qjsbind::Context* context = qjsbind::Context::get(ctx);
 5     if(!context)
 6         context = new qjsbind::Context(ctx);
 7     qjsbind::Module *module = context->NewModule(module_name);
 8     Exp_Utils(module);
 9     return module->module();
10 }
11 
12 extern "C"
13 __declspec(dllexport) void js_uninit_module(JSContext * ctx)
14 {
15     qjsbind::Context* context = qjsbind::Context::get(ctx);
16     if(context && context->isAttached())
17         delete context;
18 }
js_init_module是在quickjs加载扩展模块时调用。这个函数的功能就是给JSContext匹配一个qjsbind::Context对象。
对于UI线程来的模块,JSContext中已经有了Context对象,但是worker线程import创建的module,JSContext中是没有qjsbind::Context对象的。此时我们需要new一个新的qjsbind::Context对象出来。
然后调用自己实现的Exp_Utils(module)方法来导出C++方法到JS中。
js_uninit_module是quickjs在释放一个module时调用(注:这是soui4js使用的quickjs扩展的功能,原版qjs没有该逻辑)
这里主要是释放在js_init_module中new的qjsbind::Context对象,防止内存泄漏。
下面我们看一下Exp_Utils的代码
void Exp_Utils(qjsbind::Module* module)
{
    module->ExportFunc("Md5", &Md5);
    module->ExportFunc("FileMd5", &FileMd5);
    module->ExportFunc("FileMd5Ex", &FileMd5Ex);
    module->ExportFunc("DelFile", &fileop::DelFile);
    module->ExportFunc("DelDir", &fileop::DelDir);
    module->ExportFunc("SelectFile", &fileop::SelectFile);
    module->ExportFunc("CopyFile", &fileop::JsCopyFile);
    module->ExportFunc("CopyDir", &fileop::JsCopyDir);

    module->ExportFunc("Base64Decode", &Base64Decode);
    module->ExportFunc("Base64Encode", &Base64Encode);

    module->ExportFunc("UrlDecode", &urldecode);
    module->ExportFunc("UrlEncode", &urlencode);

    module->ExportFunc("PlaySound", &sysapi::JsPlaySound);
}
 module->ExportFunc("Md5", &Md5); 这一行的意思是将C++函数Md5导出到JS中,名字就是"Md5"。
下面我们看一下Md5函数的原型:
std::string Md5(const char* buf, int length) {
    unsigned char digest[16];
    MD5_CTX context;
    MD5Init(&context);
    MD5Update(&context, (const unsigned char*)buf, length);
    MD5Final(digest, &context);
    return MDPrint(digest);
}
可以看出,这个函数和普通的C函数并没有什么不同。所有输入输出参数和JS的交换都在qjsbind中自动进行了处理。

   Exp_Utils方法中,使用qjsbind::Module->ExportFunc方法,非常方便的实现了将C++方法导出到JS中。

   qjsbind中对于常见的数据类型都做了处理。但是如果要支持用户自己的特定数据类型,则还是需要用户自己对特定参数类型做模板特化。

注意:
原本quickjs也提供了开发扩展模块的框架,在原框架中,用户导出一个函数到JS要逐个处理qjs的输入输出参数,使用起来比较麻烦,使用本文的方法,借助qjsbind模块提供的模板方法,可以更简单方便的实现这个过程。

标签:qjsbind,第三篇,context,ExportFunc,module,C++,模块,Context,soui4js
From: https://www.cnblogs.com/setoutsoft/p/17496297.html

相关文章

  • C++ 中的运算符重载
     您可以重定义或重载大部分C++内置的运算符。这样,您就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字operator和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。https://www.lekaowang.com/jszgz/z......
  • C++ 中的函数重载
     在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。https://www.lekaowang.com/jszgz/zxj/lfb/......
  • C++ 多态
     多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。https://www.lekaowang.com/zhxfgcs/kfx/0j0/......
  • C语言与C++不得不说的那点事
    说到C语言,就不得不说它的继承者——C++语言。众所周知,C++语言是在C语言的基础上,添加了面向对象、模板等现代程序设计语言的特性而发展起来的。两者无论是从语法规则上,还是从运算符的数量和使用上,都非常相似,所以我们常常将这两门语言统称为“C/C++”。虽然因为天然的血缘关系,导致两......
  • 2009第二届C++技术大会即将在上海隆重召开
     2009第二届C++  C++对于现代软件的发展功不可没,特别是在系统软件开发领域,C++扮演着关键的角色。中国作为全球软件产业最具潜力的市场,越来越多的企业认识到了C++及相关系统软件技术在软件产业中举足轻重的作用。 为了推动C++及相关系统软件技术在国内的深度应用......
  • C++17之std::any
    一般来说,c++是一种具有类型绑定和类型安全性的语言。值对象声明为具有特定类型,该类型定义哪些操作是可能的以及它们的行为方式。值对象不能改变它们的类型。std:any是一种值类型,它能够更改其类型,同时仍然具有类型安全性。也就是说,对象可以保存任意类型的值,但是它们知道当前保存......
  • C++面试八股文:static_cast了解一下?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第20面:面试官:C++中支持哪些类型转换?二师兄:C++支持C风格的类型转换,并在C++11引入新的关键字规范了类型转换。二师兄:C++11引入四种新的类型转换,分别是static_cast、dynamic_cast、const_cast、和reinterpret_cast。二师兄:static_c......
  • C++面试八股文:static_cast了解一下?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第20面:面试官:C++中支持哪些类型转换?二师兄:C++支持C风格的类型转换,并在C++11引入新的关键字规范了类型转换。二师兄:C++11引入四种新的类型转换,分别是static_cast、dynamic_cast、const_cast、和reinterpret_cast。二师兄:static_ca......
  • C++ 智能指针
    unique_ptrunique_ptr为了避免重复释放(doublefree)问题出现,进行拷贝(删除了拷贝构造函数)这样的特性带来的问题是无法进行参数传递(因为参数传递需要拷贝构造函数),有两种解决方法想要解决这个问题,首先需要理解为什么unique_ptr会禁止拷贝,对一个指针进行拷贝......
  • 《C++》文件操作
    C++本地文件读写引用头文件<fstream>操作文件三大类ofstream:写操作ifstream:读操作fstream:读写操作打开方式解释ios::in读ios::out写ios::ate初始位置:文件尾ios::app追加方式写文件ios::trunc如果文件存在先删除在创建ios::binary二进制方式PS:文件打开方式可以配合使用,利用“|”......