From 3fc8685114c1c314d0b6983a404db61b9bd08f47 Mon Sep 17 00:00:00 2001 From: yinkanglong Date: Thu, 10 Sep 2020 21:57:36 +0800 Subject: [PATCH] js --- NodeJS/11C++插件.md | 148 ++++++++++++++++++++++++++++++++++++++ NodeJS/12Electron.md | 0 工作日志/2020年9月10日.md | 0 工作日志/2020年9月9日.md | 4 +- 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 NodeJS/11C++插件.md create mode 100644 NodeJS/12Electron.md create mode 100644 工作日志/2020年9月10日.md diff --git a/NodeJS/11C++插件.md b/NodeJS/11C++插件.md new file mode 100644 index 00000000..cc442bd9 --- /dev/null +++ b/NodeJS/11C++插件.md @@ -0,0 +1,148 @@ +## 1 应用场景 + +### Automation +​ 如果您的c++运行作为一个独立的命令行,您不需要源代码来利用选项1 -automation 选项。您可以使用Node的子进程API 运行您的c++程序。这个选项适用于将任何东西带到web上——如果你只是运行它的话,你的命令行程序写在什么语言上并没有什么区别。如果您正在阅读这篇文章,希望获得C代码、Fortran代码或其他一些语言,那么这个选项值得一读。 + +​ 自动化选项不仅仅针对那些没有c++代码的人。如果您有c++代码,或者可以很容易地转换成命令行程序,那么这个选项是合理的,如果您可以使用性能,并且您并不想陷入语言集成的麻烦中。 + +### Shared Library / DLL +​ 如果您处理的是c++ dll/lib,或者您有c++源代码,并且可以进行适当的修改,以创建动态库,那么 shared library 方法可能对您很有效。在本章中,我们将详细介绍如何使用外部函数接口模块进行此操作。这个选项可以让您更精确地控制如何将c++集成到节点中,因为对c++例程的调用通常可以直接写到Node.js代码中。虽然这种方法可以使您更接近完整的集成,但是您仍然需要处理类型转换和在调用c++时阻塞。如果您想要更好的集成,这是一个很好的选择,而无需花费大量时间来处理V8。 + +### Node.js Addon +​ 如果您有c++源代码,那么第三个选项是创建一个本机 Node.js模块调用你的c++。虽然这是一个更具挑战性的方法,但是您获得了大量的灵活性和性能。您还可以选择异步调用您的c++,这样您就不会阻塞web应用程序的事件循环,而c++正在处理数字。当我们在本节中介绍这部分内容时,它将主要作为对书中主要章节中已经介绍的材料的回顾。 + +## 2 插件实现 + +### 主要的方案 +> 当前主流的方法,就是最简单的napi。下面是其发展过程。 +* 使用nodejs和v8原生的API实现C++接口的编译工作.是nodejs和V8引擎原生的API,代码级别的API。会随着版本进行演进,并且十分难搞。 +* 使用第三方的nan库进行API实现。也已经淘汰。 +* 使用N-API实现C++接口的编译工作。经过nodejs官方封装的二进制借口文件,ABI。接口稳定,并且向后兼容。 +* 使用EFF网络中的调用DLL的方法。 + + +## 3 n-api +### 背景 +* 以 C 的风格提供稳定 ABI 接口; +* 消除 Node.js 版本的差异; +* 消除 JavaScript 引擎的差异(如 Google V8、Microsoft ChakraCore 等) + +### 特性 +* 提供头文件 node_api.h; +* 任何 N-API 调用都返回一个 napi_status 枚举,来表示这次调用成功与否; +* N-API 的返回值由于被 napi_status 占坑了,所以真实返回值由传入的参数来继承,如传入一个指针让函数操作; +* 所有 JavaScript 数据类型都被黑盒类型 napi_value 封装,不再是类似于 v8::Object、v8::Number 等类型; +* 如果函数调用不成功,可以通过 napi_get_last_error_info 函数来获取最后一次出错的信息。 + +### 初始化 +* 引入头文件 + +```C +#define NAPI_VERSION 3//NAPI_VERSION for the given release of Node.js. +#include +``` + +```C +void Init(napi_env env, napi_value exports, napi_value module, void* priv) +{ + napi_status status; + + // 用于设置 exports 对象的描述结构体 + napi_property_descriptor desc = + { "echo", 0, Echo, 0, 0, 0, napi_default, 0 }; + + // 把 "echo" 设置到 exports 去 + status = napi_define_properties(env, exports, 1, &desc); +} + +NAPI_MODULE(addon, Init) +``` +napi_property_descriptor 是用于设置对象属性的描述结构体,它的声明如下: +``` + + +typedef struct { + const char* utf8name; + + napi_callback method; + napi_callback getter; + napi_callback setter; + napi_value value; + + napi_property_attributes attributes; + void* data; +} napi_property_descriptor; +``` + +### 函数声明 +通过 napi_get_cb_info 获取当次函数请求的参数信息,包括参数数量和参数体(参数体以 napi_value 的数组形式体现); +``` +napi_value Echo(napi_env env, napi_callback_info info) +{ + napi_status status; + + size_t argc = 1; + napi_value argv[1]; + status = napi_get_cb_info(env, info, &argc, argv, 0, 0); + if(status != napi_ok || argc < 1) + { + napi_throw_type_error(env, "Wrong number of arguments"); + return 0; // napi_value 实际上是一个指针,返回空指针表示无返回值 + } + + return argv[0]; +} +``` + + + + + +## 4 构建 +### C/C++编译工具 +* Linux +``` +gcc编译环境 +``` +* windows +``` +visual Studio offers all the required compiler tools. \\or +npm install --global windows-build-tools +``` + + +### node-gyp构建工具 +* node-gyp 是基于 GYP4 的。它会识别包或者项目中的 binding.gyp5 文件,然后根据该配置文件生成各系统下能进行编译的项目,如 Windows 下生成 Visual Studio 项目文件(*.sln 等),Unix 下生成 Makefile。在生成这些项目文件之后,node-gyp 还能调用各系统的编译工具(如 GCC)来将项目进行编译,得到最后的动态链接库 *.node 文件。 +* 项目构建的描述文件binding.gpy +``` +{ + "targets": [{ + "target_name": "addon1", + "sources": [ "1/addon.cc", "1/myobject.cc" ] + }, { + "target_name": "addon2", + "sources": [ "2/addon.cc", "2/myobject.cc" ] + }, { + "target_name": "addon3", + "sources": [ "3/addon.cc", "3/myobject.cc" ] + }, { + "target_name": "addon4", + "sources": [ "4/addon.cc", "4/myobject.cc" ] + }cmake-jsre:通过当前目录的 binding.gyp 生成项目文件,如 Makefile 等; +$ node-gyp build:将当前项目进行构建编译,前置操作必须先 configure; +$ node-gyp clean:清理生成的构建文件以及输出目录,说白了就是把目录清理了; +$ node-gyp rebuild:相当于依次执行了 clean、configure 和 build; +$ node-gyp install:手动下载当前版本的 Node.js 的头文件和库文件到对应目录。 +``` + +* 在我们编译一个 C++ 原生扩展的时候,它会去指定目录下(通常是 ~/.node-gyp 目录下)搜我们当前 Node.js 版本的头文件和静态连接库文件。 +### cmake-js构建工具 + +CMake.js is an alternative build system based on CMake.CMake.js is a good choice for projects that already use CMake or for developers affected by limitations in node-gyp. + + +## 5 步骤 + +1. 首先使用v8编写nodejs支持的C++接口文件。或者使用n-api +2. 然后编写binding.gyp,使用node-gyp配置并将C++文件编译成nodejs的模块。其中,调用了cmake编译工具进行搬移。 +3. 然后在js文件中引入模块。调用并输出结果。 \ No newline at end of file diff --git a/NodeJS/12Electron.md b/NodeJS/12Electron.md new file mode 100644 index 00000000..e69de29b diff --git a/工作日志/2020年9月10日.md b/工作日志/2020年9月10日.md new file mode 100644 index 00000000..e69de29b diff --git a/工作日志/2020年9月9日.md b/工作日志/2020年9月9日.md index 19ecd0af..2a79b3c9 100644 --- a/工作日志/2020年9月9日.md +++ b/工作日志/2020年9月9日.md @@ -2,8 +2,8 @@ ## 技术范式 -> 1. 选择合适的技术范式。√ -> 2. 对技术细节进行学习了解 +> 1. 选择合适的技术范式。√====>electron +> 2. 对技术细节进行学习了解√====>javascript,nodejs,electron > 3. 寻找开源的模板代码搭建框架 > 4. 根据任务需求进行快速开发