您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

如何为Electron应用开发原生模块

时间:2023-12-26 13:24:52  来源:微信公众号  作者:大转转FE

大家都知道JAVAScript无论是在浏览器中运行、还是在Node.js中运行都是单线程运行的,所以并不适合在处理一些CPU密集型任务。但是Node.js允许开发者使用C、C++等语言开发像普通的Node.js模块一样通过require()函数加载的原生模块。因为Electron内置Node.js,这样就使得Electron同样具备了相同的能力。

在实际业务场景中,也有一些现成的C/C++项目,在Node.js项目中直接复用可以节约很多开发成本。

本文将探讨如何在Electron应用中开发原生模块,以扩展应用的功能和性能。

搭建原生模块开发环境

在目前的原生模块开发中,一般都是基于Node-Api进行开发。

Node-Api是什么呢?

Node-API(Node Application Programming Interface)是一个用于编写跨平台原生插件的封装层。它提供了一组稳定的 C/C++ 函数,使开发者可以编写与 Node.js 运行时环境兼容的原生插件。通过使用 Node-API,开发者可以消除由于 Node.js 版本变化而引起的插件不兼容的问题,并且能够更方便地编写和维护跨平台的原生模块。

理解一下就是我们无需为不同版本的Node.js编译不同版本的原生模块。不同版本的 Node.js 使用同样的接口为原生模块提供服务,这些接口是 ABI 化的,只要 ABI 的版本号一致,编译好的原生模块就可以直接使用,而不需要重新编译。

ABI 化是指将软件接口转化为应用程序二进制接口(Application Binary Interface)的过程。在编程中,ABI 化的目标是确保在不同编译器、操作系统以及硬件平台之间的二进制兼容性。通过将接口规范化为二进制标准,不同模块或程序可以相互调用和交互,而无需关心具体实现细节和底层平台差异。Node-API 的设计就是为了实现跨版本和跨平台的 ABI 兼容性,以便 C/C++ 模块能够在不同的 Node.js 环境中无需重新编译即可运行。

Node-API有哪些开发方式?

基于 Node-API 的原生模块开发可以使用 C 语言或者基于 node-addon-api 项目使用 C++ 语言的两种方式。

  1. 基于C语言开发:由于受众为前端开发者,C语言的编程复杂度高、开发效率较低,开发过程可能较为繁琐。
  2. 基于 node-addon-api项目开发:相对于纯 C 语言开发,C++ 提供了更多的高级特性和工具,开发效率相对较高。node-addon-api 项目提供了一组方便的 C++ API 封装,简化了与 Node-API 的交互过程,减少了部分底层操作。

接下来我们就基于这个项目来开发一个 Electron 的原生模块。

  1. 安装 Node.js:首先,确保您已经安装了 Node.js,可以从 Node.js 官网下载并安装适合您操作系统的版本。
  2. 需要全局安装 node-gyp,它是专门为构建开发、编译原生模块环境而生的跨平台命令行工具。
npm install -g node-gyp
  1. 创建空项目目录:创建一个新的项目目录,作为原生模块的开发目录。
  2. 初始化 npm 项目:进入项目目录,打开终端,并运行以下命令初始化 npm 项目。
 
npm init
  1. 根据提示,设置项目的名称、版本等信息。
  2. 安装 node-addon-api:运行以下命令安装 node-addon-api 模块:
npm install node-addon-api --save-dev

以上就已经搭建好了基本的原生模块开发环境,接下来通过一个简单的例子,来实现一个访问系统文件的原生模块带大家了解一下开发流程。

开发原生模块访问系统文件并读取文件内容

开发原生模块需要熟悉C++编程和Node.js的C/C++扩展开发,涉及一些底层的编程和跨平台的知识。这里的例子较为简单,方便大家理解。

  1. 创建 C++ 文件:在项目目录下创建一个 C++ 源文件,例如 filesystem.cpp,并添加以下代码内容:
#include <napi.h>
#include <IOStream>
#include <fstream> 

Napi::String ReadFile(const Napi::CallbackInfo& info) { 

    Napi::Env env = info.Env(); 

    // 读取文件路径参数 
    std::string filePath = info[0].As<Napi::String>().Utf8Value(); 

    // 打开文件并读取内容 std::ifstream file(filePath);
    std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    file.close();

    // 将内容转换为 Napi::String 返回 
    return Napi::String::New(env, content); 
} 

Napi::Object Init(Napi::Env env, Napi::Object exports) { 
    exports.Set("readFile", Napi::Function::New(env, ReadFile));
    return exports; 
}
NODE_API_MODULE(addon, Init)

上述代码定义了一个 ReadFile 函数,它接受一个文件路径参数,并返回文件的内容。

NODE_API_MODULE是Node-API 提供的一个重要的宏,用于在 C++ 中定义 Node.js 原生模块的入口点,创建一个模块初始化函数,并将此函数暴露给 Node.js 运行时。

使用 NODE_API_MODULE 定义原生模块的入口点,可以让开发者以 C++ 的方式编写模块的初始化、导出函数、属性等,并与 Node.js 运行时进行交互。并可以在 Node.js 中加载和使用。

Init 函数是模块的初始化函数,用于在模块加载时注册和导出相应的函数、属性等。然后,通过 NODE_API_MODULE 将 Init 函数暴露给 Node.js 运行时,并指定模块的名字为 "addon"。

  1. 创建 binding.gyp 文件:在项目目录中创建一个名为 binding.gyp 的文件,并添加以下内容:
{ 
    "targets": [ 
        { 
            "target_name": "filesystem", 
            "sources": ["filesystem.cpp"]
        }
}

binding.gyp 是一个用于配置 Node.js 原生模块构建过程的项目文件。它采用了 JSON 格式,并使用特定的语法来定义编译选项、依赖项和源文件等信息。通过编辑 binding.gyp 文件,可以指定编译器和链接器的选项,添加所需的依赖库,并确定要编译的源文件。

编译原生模块

在构建编译原生模块时,需要使用 node-gyp ,它会读取 binding.gyp 文件并根据其内容进行编译操作。node-gyp 提供了一个简化的构建流程,使得开发人员能够轻松地配置和构建原生模块。

使用以下命令构建该模块。

$ node-gyp configure 
$ node-gyp build

运行上述命令将生成一个名为 build/Release/filesystem.node 的编译好的原生模块文件。

接下来,就可以在任何 Node.js 文件中使用该模块:创建一个名为 app.js 的 JavaScript 文件,并添加以下代码

const addon = require('./build/Release/filesystem.node'); 

const filePath = '/path/to/file.txt'; 

const content = addon.readFile(filePath); 

console.log(content);

上述代码使用 require 导入原生模块,然后调用 readFile 函数读取指定文件的内容,并输出到控制台。

总结

在 Electron 应用中,使用和开发原生模块可以为前端开发同学提供更广阔的可能性;能够利用操作系统级别的功能来提升应用的性能。

那么有同学就会有疑问,除了自己开发原生模块还有什么方案可以给Electron应用提供更广泛的功能扩展,包括底层系统功能的访问、高性能计算呢?

当然有,在日常开发中,可以使用动态链接库(Dynamic Link Library,DLL)进行扩展功能的模块化。使用动态链接库可以使用更多的语言和框架进行开发,适合不同开发者的需求。比如,一个go开发者也可以给我们提供一个动态链接库供Electron调用,也可以将go代码打包成不同平台的文件供其他平台调用,更适合独立功能各个平台使用的场景。原生模块则更专注于为 Node.js 和 Electron 应用程序提供特定功能的开发。

在实际应用中,可根据具体需求和开发团队的技术栈来选择合适的方式,结合动态链接库和原生模块来扩展 Electron 应用程序的功能。

参考链接

  • Electron桌面应用开发:https://juejin.cn/book/7152717638173966349?enter_from=course_center&utm_source=course_center
  • node-gyp 实现 nodejs 调用 C++:https://juejin.cn/post/6844903971220357134?searchId=20231214152519329167E9F0AB744365BF


Tags:Electron   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  Search: Electron  点击:(46)  评论:(0)  加入收藏
如何为Electron应用开发原生模块
大家都知道JavaScript无论是在浏览器中运行、还是在Node.js中运行都是单线程运行的,所以并不适合在处理一些CPU密集型任务。但是Node.js允许开发者使用C、C++等语言开发像普...【详细内容】
2023-12-26  Search: Electron  点击:(80)  评论:(0)  加入收藏
Electron、Vite和Vue 3助你打造功能丰富桌面应用
Vite的快速热更新能力和Vue 3的高效性能,加速了开发周期,使得开发者能够更快地迭代和测试应用。很多vue3的UI可以使用,例如本文选用的arco-design,这就是站在巨人肩膀之上。背景...【详细内容】
2023-08-28  Search: Electron  点击:(282)  评论:(0)  加入收藏
使用Electron打造跨平台程序需要关注的技术点
背景上篇文章已经介绍了使用electron forge+vite+vue3来实现一个桌面应用程序的框架。本文重点介绍完善一个这样的框架的几个通用的需求点及实现方式。需求 实现客户端在线...【详细内容】
2023-08-15  Search: Electron  点击:(175)  评论:(0)  加入收藏
Electron是目前最好的桌面框架吗?
如果您正在尝试使用JavaScript构建桌面应用程序,您可能至少考虑过Electron。GitHub于2013年为其Atom编辑器发布了Electron,并被Microsoft、Discord和Slack等许多大公司使用。...【详细内容】
2023-01-04  Search: Electron  点击:(382)  评论:(0)  加入收藏
使用.NET5、Blazor和Electron.NET构建跨平台桌面应用
Electron.NET是一个嵌入了ASP.NET Core的Electron的封装,通过Electron.NET可以构建基于.NET5的跨平台的桌面应用,使得开发人员只需要使用ASP.NET Core和 Blazor就可以胜任桌面...【详细内容】
2021-11-30  Search: Electron  点击:(866)  评论:(0)  加入收藏
electron 打包vue为桌面应用的详细过程
1.vue create demo2.vue ui3.搜索 vue-cli-plugin-electron-builder,勾选,安装4.npm run electron:serve5.npm run electron:build6.build complete!构建完成!构建完成后,看一...【详细内容】
2021-09-09  Search: Electron  点击:(516)  评论:(0)  加入收藏
Electron 简介
本教程我们来学习 Electron 的基础知识,下面我们先来学习一下什么是 Electron。Electron是什么Electron 是是 GitHub 开发的一个开源框架。它允许使用 Node.js(作为后端)和 Chr...【详细内容】
2021-05-18  Search: Electron  点击:(9662)  评论:(0)  加入收藏
基于 Vue3.0+Electron 搭建桌面端应用
目前electron最新稳定版本为v11.2.1,star高达89.2K+。# 官网地址https://www.electronjs.org/# 仓库地址https://github.com/electron/electron有数千个超优秀的软件是基于E...【详细内容】
2021-02-08  Search: Electron  点击:(2523)  评论:(0)  加入收藏
electron-builder 打包生成桌面App
开发electron客户端程序,打包是绕不开的问题。如何使用来源:https://www.php.cn/div-tutorial-411690.htmlbuilder的使用和配置都是很简单的builder配置有两种方式package.jso...【详细内容】
2020-08-07  Search: Electron  点击:(1716)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(5)  评论:(0)  加入收藏
站内最新
站内热门
站内头条