什么酒不能喝脑筋急转弯| 什么叫桥本甲状腺炎| 女人吃洋葱有什么好处| 龟头炎吃什么药| 平身是什么意思| 小孩风热感冒吃什么药| 澳大利亚位于什么板块| 地黄泡水喝有什么好处| 家里为什么会有壁虎| 安徒生被誉为什么| 锻练与锻炼有什么区别| 抑郁症是什么意思| 荷花的寓意是什么| 拉绿色的屎是什么原因| 做肠镜有什么危害| 28.88红包代表什么意思| 一龙一什么填十二生肖| 大象的耳朵有什么作用| 女人大腿内侧黑是什么原因引起的| 小孩掉头发是什么原因| 给小孩买什么保险好| 马失前蹄下一句是什么| 陆代表什么数字| 短裙配什么鞋子好看| 阳虚吃什么调理| 耳朵聋是什么原因| 汉菜不能和什么一起吃| 观音菩萨叫什么名字| ltp什么意思| ubc是什么意思| 肾结石要忌口什么东西| 2000年出生属什么| 米五行属什么| 呼吸内镜检查什么| 什么是边界感| 男人吃洋葱有什么好处| 白内障吃什么药| 摧枯拉朽是什么意思| 子宫切除后对身体有什么影响| 宫颈柱状上皮外移是什么意思| 3.1415926是什么意思| 2030年是什么年| 英红九号是什么茶| 高血糖吃什么| 精神科主要看什么病| 男模什么意思| 什么是http| 子宫回声欠均匀是什么意思| 一段奶粉和二段奶粉有什么区别| 黄晓明的老婆叫什么名字| 中午12点到1点是什么时辰| 背信弃义是什么意思| cosmo是什么意思| 中暑了吃什么| 什么中药可以降糖| 观音土是什么| 属猴的守护神是什么菩萨| 水加日念什么| 一什么瓦| 骨扫描是检查什么| 1932年属什么| aml是什么病| 胃疼吃什么药好得最快最有效| 3月25号是什么星座| 桑葚有什么作用| 碳水化合物指的是什么食物| 扁桃体发炎是什么原因引起的| 四川古代叫什么| 儿童感冒咳嗽吃什么药| 邂逅什么意思| 胃消化不好吃什么调理| 曹操是什么时期的人| 海马萎缩是什么情况| 禁锢是什么意思| 脸小适合什么发型| 眼睛出现重影是什么原因| 中暑吃什么药| 蟹柳是什么做的| 儿童内分泌科检查什么| 多吃蔬菜有什么好处| 端午节吃什么| 气胸是什么病是大病吗| 螨虫咬了是什么样子| 梁下放床有什么禁忌| 痛风是什么原因引起的| 机警是什么意思| 为什么身上一热就痒| 查肝胆胰脾肾挂什么科| 暑假什么时候结束| 什么是地中海饮食| 治疗狐臭最好的方法是什么| 冰心的原名叫什么| 养神经的药是什么药最好| 智齿拔了有什么影响| ttm是什么意思| 包皮过长有什么影响| 瓤是什么意思| 拉黄水是什么原因| 牛在五行中属什么| 小受是什么意思| 文字属于五行属什么| 用什么香皂洗脸可以祛痘| 农历六月十一是什么星座| 心跳慢是什么原因| 丝瓜长什么样| 测怀孕的试纸叫什么| 额头有痣代表什么| 什么叫绝对值| 心语是什么意思| 喝什么降血压| 三个土读什么| 豆豉是什么东西| 黄芪什么人不能喝| 即使什么也什么| 榴莲为什么那么贵| 脚突然肿了是什么原因| 3月16日什么星座| 芥菜什么时候种| 原研药是什么意思| 眼睛眼屎多是什么原因| 尿血是什么问题| 大腿前侧是什么经络| 四叶草代表什么| 骨质增生挂什么科| 鸟屎掉手上有什么预兆| 二战时期是什么时候| 鸡肉和什么菜搭配最好| 藿香正气水治疗什么病| 老是睡不着觉是什么原因| 虎皮膏药有什么功效| 拉肚子吃什么药好使| 男性硬下疳是什么样子| 吃什么东西补气血| 有冬瓜西瓜南瓜为什么没有北瓜| 嗓子疼挂什么科| 怎么知道自己五行缺什么| 牙齿黑是什么原因| 怀不上孕是什么原因造成的| 梭织面料是什么面料| 为什么流鼻血| 异类是什么意思| 黄瓜可以和什么一起榨汁| 炭疽病用什么农药最好| 检查胰腺做什么检查| 屁为什么是臭的| 7月去青海带什么衣服| 上热下寒吃什么中成药| 食用植物油是什么油| 属兔适合佩戴什么饰品| 什么叫稽留流产| 咳嗽有痰吃什么水果| 明五行属什么| 熤是什么意思| 老花眼是什么症状| 三叉神经痛有什么症状| 总胆固醇高是什么原因| 吃什么排便顺畅| 血小板为什么会减少| 冬至吃什么| 相处是什么意思| 荣五行属什么| 万年历是什么| 医院脱毛挂什么科| m是什么尺码| 眼睛干涩吃什么中成药| 格拉苏蒂手表什么档次| 焦虑挂什么科| 胃胀疼是什么原因| 为什么会突然得荨麻疹| 红参适合什么人吃| 贫血喝什么口服液最好| 6月20号什么星座| 粘米粉是什么米做的| 相敬如宾是什么生肖| 睡觉嗓子干是什么原因| 前胸后背疼是什么病| 猫的胡子有什么作用| 做梦吃鱼是什么意思| 梦见洪水是什么意思| 中国第一艘航空母舰叫什么| 右侧卵巢多囊样改变是什么意思| 蝴蝶花长什么样| 青蛙是什么| 乳房看什么科| 蜜糖有什么功效和作用| 眼睛斜视是什么原因| 胡塞武装是什么| 轻度脂肪肝有什么症状| 平坦的反义词是什么| 做核磁共振挂什么科| 中耳炎不能吃什么食物| 阿斯利康是什么药| 结肠炎吃什么食物好| 什么网站可以看黄色视频| 小孩子发烧手脚冰凉是什么原因| 乳头大是什么原因| 属龙女和什么属相最配| anca医学上是什么意思| 鱼石脂是什么| 请大家知悉是什么意思| 梦见自己的手机丢了是什么意思| 1943年属什么| 2010属什么| 半夜饿是什么原因| 胎盘位于前壁是什么意思| xswl是什么意思| 喜鹊进家有什么预兆| 为什么会排卵期出血| 肛门痒痒的是什么原因| 什么寒什么暖| 皮炎是什么症状| 处级是什么级别| 门口放什么植物好风水| 无名指为什么叫无名指| 无机盐是什么| 新五行属什么| johnny什么意思| 儿保做些什么检查项目| 智是什么意思| on是什么牌子| 为什么月经每个月提前| 心脏不舒服做什么检查| 吃什么可以降低尿酸| 沙僧是什么动物| 拉开帷幕是什么意思| 暗物质和暗能量是什么| 但微颔之的之是什么意思| 雪莲果什么季节成熟| 舒张压是什么意思| 姻缘是什么意思| 腮帮子疼吃什么药| 象代表什么生肖| 太公是什么意思| 导师是什么意思| 三维彩超主要检查什么| 肾结石吃什么药能化石| 昆山有什么好玩的地方| 山茶花是什么颜色| 野格是什么酒| 政五行属什么| 为什么近亲不能结婚| 沈腾和马丽是什么关系| 现在做什么最赚钱| 臻的意思是什么| 陶字五行属什么| 花生不能和什么食物一起吃| 腮腺炎吃什么药最管用| 鸦片鱼又叫什么鱼| 南瓜炒什么好吃| 尿潜血阳性什么意思| 大自然是什么意思| cosplay是什么意思| 羽立读什么| img什么意思| 巨蟹女和什么座最配对| 2月26日什么星座| 苏轼是什么派诗人| 什么条什么理| 海米是什么东西| 梦见自己会开车了是什么意思| 牙龈肿是什么原因引起的| metoo是什么意思| 高压偏低是什么原因造成的| 海啸是什么意思| 百度
Skip to main content

独家:2016年10个板块火热题材概念龙头股(名单

百度   田玲在接受记者采访时谈到,当地计划安装25个摄像头以加强对犯罪行为的监控和威慑,目前已安装12个,其中5个是几年前警察局在敏感街区地铁口安装的,7个是去年至今安装的,今年计划将其余13个摄像头安装到位。

One of Electron's most powerful features is the ability to combine web technologies with native code - both for compute-intensive logic as well as for the occasional native user interface, where desired.

Electron does so by building on top of "Native Node.js Addons". You've probably already come across a few of them - packages like the famous sqlite use native code to combine JavaScript and native technologies. You can use this feature to extend your Electron application with anything a fully native application can do:

  • Access native platform APIs not available in JavaScript. Any macOS, Windows, or Linux operating system API is available to you.
  • Create UI components that interact with native desktop frameworks.
  • Integrate with existing native libraries.
  • Implement performance-critical code that runs faster than JavaScript.

Native Node.js addons are dynamically-linked shared objects (on Unix-like systems) or DLL files (on Windows) that can be loaded into Node.js or Electron using the require() or import functions. They behave just like regular JavaScript modules but provide an interface to code written in C++, Rust, or other languages that can compile to native code.

Tutorial: Creating a Native Node.js Addon for Electron

This tutorial will walk you through building a basic Node.js native addon that can be used in Electron applications. We'll focus on concepts common to all platforms, using C++ as the implementation language. Once you complete this tutorial common to all native Node.js addons, you can move on to one of our platform-specific tutorials.

Requirements?

This tutorial assumes you have Node.js and npm installed, as well as the basic tools necessary for compiling code on your platform (like Visual Studio on Windows, Xcode on macOS, or GCC/Clang on Linux). You can find detailed instructions in the node-gyp readme.

Requirements: macOS?

To build native Node.js addons on macOS, you'll need the Xcode Command Line Tools. These provide the necessary compilers and build tools (namely, clang, clang++, and make). The following command will prompt you to install the Command Line Tools if they aren't already installed.

xcode-select --install

Requirements: Windows?

The official Node.js installer offers the optional installation of "Tools for Native Modules", which installs everything required for the basic compilation of C++ modules - specifically, Python 3 and the "Visual Studio Desktop development with C++" workload. Alternatively, you can use chocolatey, winget, or the Windows Store.

Requirements: Linux?

1) Creating a package?

First, create a new Node.js package that will contain your native addon:

mkdir my-native-addon
cd my-native-addon
npm init -y

This creates a basic package.json file. Next, we'll install the necessary dependencies:

npm install node-addon-api bindings
  • node-addon-api: This is a C++ wrapper for the low-level Node.js API that makes it easier to build addons. It provides a C++ object-oriented API that's more convenient and safer to use than the raw C-style API.
  • bindings: A helper module that simplifies the process of loading your compiled native addon. It handles finding your compiled .node file automatically.

Now, let's update our package.json to include the appropriate build scripts. We will explain what these specifically do further below.

package.json
{
"name": "my-native-addon",
"version": "1.0.0",
"description": "A native addon for Electron",
"main": "js/index.js",
"scripts": {
"clean": "node -e \"require('fs').rmSync('build', { recursive: true, force: true })\"",
"build": "node-gyp configure && node-gyp build"
},
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^8.3.0"
},
"devDependencies": {
"node-gyp": "^11.1.0"
}
}

These scripts will:

  • clean: Remove the build directory, allowing for a fresh build
  • build: Run the standard node-gyp build process to compile your addon

2) Setting up the build system?

Node.js addons use a build system called node-gyp, which is a cross-platform command-line tool written in Node.js. It compiles native addon modules for Node.js using platform-specific build tools behind the scenes:

  • On Windows: Visual Studio
  • On macOS: Xcode or command-line tools
  • On Linux: GCC or similar compilers

Configuring node-gyp?

The binding.gyp file is a JSON-like configuration file that tells node-gyp how to build your native addon. It's similar to a make file or a project file but in a platform-independent format. Let's create a basic binding.gyp file:

binding.gyp
{
"targets": [
{
"target_name": "my_addon",
"sources": [
"src/my_addon.cc",
"src/cpp_code.cc"
],
"include_dirs": [
"<!@(node -p \"require('node-addon-api').include\")",
"include"
],
"dependencies": [
"<!(node -p \"require('node-addon-api').gyp\")"
],
"defines": [
"NODE_ADDON_API_CPP_EXCEPTIONS"
],
"cflags!": ["-fno-exceptions"],
"cflags_cc!": ["-fno-exceptions"],
"xcode_settings": {
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
"CLANG_CXX_LIBRARY": "libc++",
"MACOSX_DEPLOYMENT_TARGET": "10.14"
},
"msvs_settings": {
"VCCLCompilerTool": {
"ExceptionHandling": 1
}
}
}
]
}

Let's break down this configuration:

  • target_name: The name of your addon. This determines the filename of the compiled module (my_addon.node).
  • sources: List of source files to compile. We'll have two files: the main addon file and our actual C++ implementation.
  • include_dirs: Directories to search for header files. The cryptic-looking line <!@(node -p \"require('node-addon-api').include\") runs a Node.js command to get the path to the node-addon-api include directory.
  • dependencies: The node-addon-api dependency. Similar to the include dirs, this executes a Node.js command to get the proper configuration.
  • defines: Preprocessor definitions. Here we're enabling C++ exceptions for node-addon-api. Platform-specific settings:
  • cflags! and cflags_cc!: Compiler flags for Unix-like systems
  • xcode_settings: Settings specific to macOS/Xcode compiler
  • msvs_settings: Settings specific to Microsoft Visual Studio on Windows

Now, create the directory structure for our project:

mkdir src
mkdir include
mkdir js

This creates:

  • src/: Where our source files will go
  • include/: For header files
  • js/: For our JavaScript wrapper

3) "Hello World" from C++?

Let's start by defining our C++ interface in a header file. Create include/cpp_code.h:

#pragma once
#include <string>

namespace cpp_code {
// A simple function that takes a string input and returns a string
std::string hello_world(const std::string& input);
} // namespace cpp_code

The #pragma once directive is a header guard that prevents the file from being included multiple times in the same compilation unit. The actual function declaration is inside a namespace to avoid potential name conflicts.

Next, let's implement the function in src/cpp_code.cc:

src/cpp_code.cc
#include <string>
#include "../include/cpp_code.h"

namespace cpp_code {
std::string hello_world(const std::string& input) {
// Simply concatenate strings and return
return "Hello from C++! You said: " + input;
}
} // namespace cpp_code

This is a simple implementation that just adds some text to the input string and returns it.

Now, let's create the addon code that bridges our C++ code with the Node.js/JavaScript world. Create src/my_addon.cc:

src/my_addon.cc
#include <napi.h>
#include <string>
#include "../include/cpp_code.h"

// Create a class that will be exposed to JavaScript
class MyAddon : public Napi::ObjectWrap<MyAddon> {
public:
// This static method defines the class for JavaScript
static Napi::Object Init(Napi::Env env, Napi::Object exports) {
// Define the JavaScript class with method(s)
Napi::Function func = DefineClass(env, "MyAddon", {
InstanceMethod("helloWorld", &MyAddon::HelloWorld)
});

// Create a persistent reference to the constructor
Napi::FunctionReference* constructor = new Napi::FunctionReference();
*constructor = Napi::Persistent(func);
env.SetInstanceData(constructor);

// Set the constructor on the exports object
exports.Set("MyAddon", func);
return exports;
}

// Constructor
MyAddon(const Napi::CallbackInfo& info)
: Napi::ObjectWrap<MyAddon>(info) {}

private:
// Method that will be exposed to JavaScript
Napi::Value HelloWorld(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();

// Validate arguments (expecting one string)
if (info.Length() < 1 || !info[0].IsString()) {
Napi::TypeError::New(env, "Expected string argument").ThrowAsJavaScriptException();
return env.Null();
}

// Convert JavaScript string to C++ string
std::string input = info[0].As<Napi::String>();

// Call our C++ function
std::string result = cpp_code::hello_world(input);

// Convert C++ string back to JavaScript string and return
return Napi::String::New(env, result);
}
};

// Initialize the addon
Napi::Object Init(Napi::Env env, Napi::Object exports) {
return MyAddon::Init(env, exports);
}

// Register the initialization function
NODE_API_MODULE(my_addon, Init)

Let's break down this code:

  1. We define a MyAddon class that inherits from Napi::ObjectWrap<MyAddon>, which handles wrapping our C++ class for JavaScript.
  2. The Init static method: 2.1 Defines a JavaScript class with a method called helloWorld 2.2 Creates a persistent reference to the constructor (to prevent garbage collection) 2.3 Exports the class constructor
  3. The constructor simply passes its arguments to the parent class.
  4. The HelloWorld method: 4.1 Gets the Napi environment 4.2 Validates input arguments (expecting a string) 4.3 Converts the JavaScript string to a C++ string 4.4 Calls our C++ function 4.5 Converts the result back to a JavaScript string and returns it
  5. We define an initialization function and register it with NODE_API_MODULE macro, which makes our module loadable by Node.js.

Now, let's create a JavaScript wrapper to make the addon easier to use. Create js/index.js:

js/index.js
const EventEmitter = require('events')

// Load the native addon using the 'bindings' module
// This will look for the compiled .node file in various places
const bindings = require('bindings')
const native = bindings('my_addon')

// Create a nice JavaScript wrapper
class MyNativeAddon extends EventEmitter {
constructor () {
super()

// Create an instance of our C++ class
this.addon = new native.MyAddon()
}

// Wrap the C++ method with a nicer JavaScript API
helloWorld (input = '') {
if (typeof input !== 'string') {
throw new TypeError('Input must be a string')
}
return this.addon.helloWorld(input)
}
}

// Export a singleton instance
if (process.platform === 'win32' || process.platform === 'darwin' || process.platform === 'linux') {
module.exports = new MyNativeAddon()
} else {
// Provide a fallback for unsupported platforms
console.warn('Native addon not supported on this platform')

module.exports = {
helloWorld: (input) => `Hello from JS! You said: ${input}`
}
}

This JavaScript wrapper:

  1. Uses bindings to load our compiled native addon
  2. Creates a class that extends EventEmitter (useful for future extensions that might emit events)
  3. Instantiates our C++ class and provides a simpler API
  4. Adds some input validation on the JavaScript side
  5. Exports a singleton instance of our wrapper
  6. Handles unsupported platforms gracefully

Building and testing the addon?

Now we can build our native addon:

npm run build

This will run node-gyp configure and node-gyp build to compile our C++ code into a .node file. Let's create a simple test script to verify everything works. Create test.js in the project root:

test.js
// Load our addon
const myAddon = require('./js')

// Try the helloWorld function
const result = myAddon.helloWorld('This is a test')

// Should print: "Hello from C++! You said: This is a test"
console.log(result)

Run the test:

node test.js

If everything works correctly, you should see:

Hello from C++! You said: This is a test

Using the addon in Electron?

To use this addon in an Electron application, you would:

  1. Include it as a dependency in your Electron project
  2. Build it targeting your specific Electron version. electron-forge handles this step automatically for you - for more details, see Native Node Modules.
  3. Import and use it just like any other module in a process that has Node.js enabled.
// In your main process
const myAddon = require('my-native-addon')
console.log(myAddon.helloWorld('Electron'))

References and further learning?

Native addon development can be written in several languages beyond C++. Rust can be used with crates like napi-rs, neon, or node-bindgen. Objective-C/Swift can be used through Objective-C++ on macOS.

The specific implementation details differ significantly by platform, especially when accessing platform-specific APIs or UI frameworks, like Windows' Win32 API, COM components, UWP/WinRT - or macOS's Cocoa, AppKit, or ObjectiveC runtime.

This means that you'll likely use two groups of references for your native code: First, on the Node.js side, use the N-API documentation to learn about creating and exposing complex structures to JavaScript - like asynchronous thread-safe function calls or creating JavaScript-native objects (error, promise, etc). Secondly, on the side of the technology you're working with, you'll likely be looking at their lower-level documentation:

百度 技术支持:蜘蛛池 www.kelongchi.com