Skip to content

C++ Addons

🎯 学习目标

  • 理解Node.js C++ Addons的原理和用途
  • 掌握使用node-gyp构建原生模块
  • 学会编写高性能的C++扩展
  • 了解V8 API和Node.js API的使用

📚 核心概念

C++ Addons简介

javascript
// C++ Addons的应用场景
const addonUseCases = {
  performance: {
    description: '性能关键的计算密集型任务',
    examples: [
      '图像/音频处理',
      '数学计算',
      '加密解密',
      '数据压缩'
    ]
  },
  systemAccess: {
    description: '访问系统级API和硬件',
    examples: [
      '操作系统调用',
      '硬件接口',
      '设备驱动',
      '系统监控'
    ]
  },
  legacyIntegration: {
    description: '集成现有的C/C++库',
    examples: [
      '第三方库绑定',
      '遗留代码重用',
      '专业算法库',
      '商业组件'
    ]
  }
};

console.log('C++ Addons应用场景:', addonUseCases);

开发环境配置

json
// package.json配置
{
  "name": "my-native-addon",
  "version": "1.0.0",
  "description": "Node.js C++ Addon示例",
  "main": "index.js",
  "scripts": {
    "build": "node-gyp rebuild",
    "clean": "node-gyp clean",
    "configure": "node-gyp configure",
    "test": "node test.js"
  },
  "devDependencies": {
    "node-gyp": "^9.0.0"
  },
  "gypfile": true
}
python
# binding.gyp配置文件
{
  "targets": [
    {
      "target_name": "addon",
      "sources": [
        "src/addon.cpp",
        "src/calculator.cpp",
        "src/async_worker.cpp"
      ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include\")"
      ],
      "dependencies": [
        "<!(node -p \"require('node-addon-api').gyp\")"
      ],
      "cflags!": [ "-fno-exceptions" ],
      "cflags_cc!": [ "-fno-exceptions" ],
      "xcode_settings": {
        "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
        "CLANG_CXX_LIBRARY": "libc++",
        "MACOSX_DEPLOYMENT_TARGET": "10.7"
      },
      "msvs_settings": {
        "VCCLCompilerTool": { "ExceptionHandling": 1 }
      }
    }
  ]
}

🛠️ 基础C++ Addon开发

简单的数学计算模块

cpp
// src/calculator.cpp
#include <napi.h>
#include <cmath>

// 简单的加法函数
Napi::Number Add(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    // 参数验证
    if (info.Length() < 2) {
        Napi::TypeError::New(env, "Expected 2 arguments").ThrowAsJavaScriptException();
        return Napi::Number::New(env, 0);
    }
    
    if (!info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Arguments must be numbers").ThrowAsJavaScriptException();
        return Napi::Number::New(env, 0);
    }
    
    // 获取参数值
    double arg0 = info[0].As<Napi::Number>().DoubleValue();
    double arg1 = info[1].As<Napi::Number>().DoubleValue();
    
    // 执行计算
    double result = arg0 + arg1;
    
    return Napi::Number::New(env, result);
}

// 复杂数学运算
Napi::Number Fibonacci(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsNumber()) {
        Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
        return Napi::Number::New(env, 0);
    }
    
    int n = info[0].As<Napi::Number>().Int32Value();
    
    // 递归计算斐波那契数列(演示用,实际应用中应该用迭代)
    std::function<long long(int)> fib = [&](int num) -> long long {
        if (num <= 1) return num;
        return fib(num - 1) + fib(num - 2);
    };
    
    long long result = fib(n);
    return Napi::Number::New(env, static_cast<double>(result));
}

// 向量运算
Napi::Array VectorAdd(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2 || !info[0].IsArray() || !info[1].IsArray()) {
        Napi::TypeError::New(env, "Expected two arrays").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
    
    Napi::Array arr1 = info[0].As<Napi::Array>();
    Napi::Array arr2 = info[1].As<Napi::Array>();
    
    uint32_t length = arr1.Length();
    if (length != arr2.Length()) {
        Napi::TypeError::New(env, "Arrays must have the same length").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
    
    Napi::Array result = Napi::Array::New(env, length);
    
    for (uint32_t i = 0; i < length; i++) {
        double val1 = arr1.Get(i).As<Napi::Number>().DoubleValue();
        double val2 = arr2.Get(i).As<Napi::Number>().DoubleValue();
        result.Set(i, Napi::Number::New(env, val1 + val2));
    }
    
    return result;
}

// 矩阵乘法
Napi::Array MatrixMultiply(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2 || !info[0].IsArray() || !info[1].IsArray()) {
        Napi::TypeError::New(env, "Expected two matrices (2D arrays)").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
    
    Napi::Array matrix1 = info[0].As<Napi::Array>();
    Napi::Array matrix2 = info[1].As<Napi::Array>();
    
    uint32_t rows1 = matrix1.Length();
    uint32_t cols1 = matrix1.Get(uint32_t(0)).As<Napi::Array>().Length();
    uint32_t rows2 = matrix2.Length();
    uint32_t cols2 = matrix2.Get(uint32_t(0)).As<Napi::Array>().Length();
    
    if (cols1 != rows2) {
        Napi::TypeError::New(env, "Matrix dimensions incompatible for multiplication").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
    
    // 创建结果矩阵
    Napi::Array result = Napi::Array::New(env, rows1);
    
    for (uint32_t i = 0; i < rows1; i++) {
        Napi::Array row = Napi::Array::New(env, cols2);
        
        for (uint32_t j = 0; j < cols2; j++) {
            double sum = 0.0;
            
            for (uint32_t k = 0; k < cols1; k++) {
                double val1 = matrix1.Get(i).As<Napi::Array>().Get(k).As<Napi::Number>().DoubleValue();
                double val2 = matrix2.Get(k).As<Napi::Array>().Get(j).As<Napi::Number>().DoubleValue();
                sum += val1 * val2;
            }
            
            row.Set(j, Napi::Number::New(env, sum));
        }
        
        result.Set(i, row);
    }
    
    return result;
}

字符串处理模块

cpp
// src/string_processor.cpp
#include <napi.h>
#include <string>
#include <algorithm>
#include <cctype>
#include <regex>

// 字符串反转
Napi::String ReverseString(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "Expected a string").ThrowAsJavaScriptException();
        return Napi::String::New(env, "");
    }
    
    std::string input = info[0].As<Napi::String>().Utf8Value();
    std::reverse(input.begin(), input.end());
    
    return Napi::String::New(env, input);
}

// 字符串压缩(简单的RLE算法)
Napi::String CompressString(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "Expected a string").ThrowAsJavaScriptException();
        return Napi::String::New(env, "");
    }
    
    std::string input = info[0].As<Napi::String>().Utf8Value();
    std::string result;
    
    if (input.empty()) {
        return Napi::String::New(env, result);
    }
    
    char currentChar = input[0];
    int count = 1;
    
    for (size_t i = 1; i < input.length(); i++) {
        if (input[i] == currentChar) {
            count++;
        } else {
            result += currentChar;
            if (count > 1) {
                result += std::to_string(count);
            }
            currentChar = input[i];
            count = 1;
        }
    }
    
    // 处理最后一个字符
    result += currentChar;
    if (count > 1) {
        result += std::to_string(count);
    }
    
    return Napi::String::New(env, result);
}

// 字符串哈希计算
Napi::Number HashString(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsString()) {
        Napi::TypeError::New(env, "Expected a string").ThrowAsJavaScriptException();
        return Napi::Number::New(env, 0);
    }
    
    std::string input = info[0].As<Napi::String>().Utf8Value();
    
    // 简单的哈希算法(djb2)
    unsigned long hash = 5381;
    for (char c : input) {
        hash = ((hash << 5) + hash) + static_cast<unsigned char>(c);
    }
    
    return Napi::Number::New(env, static_cast<double>(hash));
}

// 正则表达式匹配
Napi::Array RegexMatch(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2 || !info[0].IsString() || !info[1].IsString()) {
        Napi::TypeError::New(env, "Expected two strings (text and pattern)").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
    
    std::string text = info[0].As<Napi::String>().Utf8Value();
    std::string pattern = info[1].As<Napi::String>().Utf8Value();
    
    try {
        std::regex regex_pattern(pattern);
        std::sregex_iterator iter(text.begin(), text.end(), regex_pattern);
        std::sregex_iterator end;
        
        Napi::Array matches = Napi::Array::New(env);
        uint32_t index = 0;
        
        for (; iter != end; ++iter) {
            const std::smatch& match = *iter;
            matches.Set(index++, Napi::String::New(env, match.str()));
        }
        
        return matches;
    } catch (const std::regex_error& e) {
        Napi::TypeError::New(env, "Invalid regex pattern").ThrowAsJavaScriptException();
        return Napi::Array::New(env);
    }
}

⚡ 异步操作处理

异步Worker实现

cpp
// src/async_worker.cpp
#include <napi.h>
#include <thread>
#include <chrono>

// 异步Worker基类
class AsyncWorker : public Napi::AsyncWorker {
public:
    AsyncWorker(Napi::Function& callback) 
        : Napi::AsyncWorker(callback), result(0) {}
    
    ~AsyncWorker() {}
    
protected:
    double result;
};

// 计算密集型异步任务
class ComputeIntensiveWorker : public AsyncWorker {
public:
    ComputeIntensiveWorker(Napi::Function& callback, int iterations)
        : AsyncWorker(callback), iterations_(iterations) {}
    
    ~ComputeIntensiveWorker() {}
    
    void Execute() override {
        // 模拟计算密集型任务
        double sum = 0.0;
        for (int i = 0; i < iterations_; i++) {
            sum += std::sin(i) * std::cos(i);
            
            // 检查是否被取消
            if (this->IsCancelled()) {
                SetError("Operation was cancelled");
                return;
            }
        }
        result = sum;
    }
    
    void OnOK() override {
        Napi::HandleScope scope(Env());
        Callback().Call({Env().Null(), Napi::Number::New(Env(), result)});
    }
    
    void OnError(const Napi::Error& e) override {
        Napi::HandleScope scope(Env());
        Callback().Call({e.Value(), Env().Undefined()});
    }

private:
    int iterations_;
};

// 异步计算函数
Napi::Value ComputeAsync(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2) {
        Napi::TypeError::New(env, "Expected iterations and callback").ThrowAsJavaScriptException();
        return env.Null();
    }
    
    if (!info[0].IsNumber() || !info[1].IsFunction()) {
        Napi::TypeError::New(env, "Invalid arguments").ThrowAsJavaScriptException();
        return env.Null();
    }
    
    int iterations = info[0].As<Napi::Number>().Int32Value();
    Napi::Function callback = info[1].As<Napi::Function>();
    
    ComputeIntensiveWorker* worker = new ComputeIntensiveWorker(callback, iterations);
    worker->Queue();
    
    return env.Undefined();
}

// Promise-based异步操作
class PromiseWorker : public Napi::AsyncWorker {
public:
    PromiseWorker(Napi::Env env, int delay) 
        : Napi::AsyncWorker(env), delay_(delay), deferred_(Napi::Promise::Deferred::New(env)) {}
    
    ~PromiseWorker() {}
    
    void Execute() override {
        // 模拟异步操作
        std::this_thread::sleep_for(std::chrono::milliseconds(delay_));
        result = delay_ * 2; // 简单的计算
    }
    
    void OnOK() override {
        deferred_.Resolve(Napi::Number::New(Env(), result));
    }
    
    void OnError(const Napi::Error& e) override {
        deferred_.Reject(e.Value());
    }
    
    Napi::Promise GetPromise() {
        return deferred_.Promise();
    }

private:
    int delay_;
    double result;
    Napi::Promise::Deferred deferred_;
};

// 返回Promise的异步函数
Napi::Promise DelayedCompute(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsNumber()) {
        auto deferred = Napi::Promise::Deferred::New(env);
        deferred.Reject(Napi::TypeError::New(env, "Expected a number").Value());
        return deferred.Promise();
    }
    
    int delay = info[0].As<Napi::Number>().Int32Value();
    
    PromiseWorker* worker = new PromiseWorker(env, delay);
    Napi::Promise promise = worker->GetPromise();
    worker->Queue();
    
    return promise;
}

对象和类的绑定

cpp
// src/native_class.cpp
#include <napi.h>
#include <vector>
#include <memory>

// 原生C++类
class Calculator {
public:
    Calculator() : value_(0.0) {}
    
    void SetValue(double value) { value_ = value; }
    double GetValue() const { return value_; }
    
    double Add(double operand) {
        value_ += operand;
        return value_;
    }
    
    double Multiply(double operand) {
        value_ *= operand;
        return value_;
    }
    
    void Reset() { value_ = 0.0; }

private:
    double value_;
};

// Node.js包装类
class CalculatorWrapper : public Napi::ObjectWrap<CalculatorWrapper> {
public:
    static Napi::Object Init(Napi::Env env, Napi::Object exports) {
        Napi::HandleScope scope(env);
        
        Napi::Function func = DefineClass(env, "Calculator", {
            InstanceMethod("setValue", &CalculatorWrapper::SetValue),
            InstanceMethod("getValue", &CalculatorWrapper::GetValue),
            InstanceMethod("add", &CalculatorWrapper::Add),
            InstanceMethod("multiply", &CalculatorWrapper::Multiply),
            InstanceMethod("reset", &CalculatorWrapper::Reset)
        });
        
        constructor = Napi::Persistent(func);
        constructor.SuppressDestruct();
        
        exports.Set("Calculator", func);
        return exports;
    }
    
    CalculatorWrapper(const Napi::CallbackInfo& info) : Napi::ObjectWrap<CalculatorWrapper>(info) {
        Napi::Env env = info.Env();
        Napi::HandleScope scope(env);
        
        calculator_ = std::make_unique<Calculator>();
    }

private:
    static Napi::FunctionReference constructor;
    std::unique_ptr<Calculator> calculator_;
    
    Napi::Value SetValue(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 1 || !info[0].IsNumber()) {
            Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
            return env.Undefined();
        }
        
        double value = info[0].As<Napi::Number>().DoubleValue();
        calculator_->SetValue(value);
        
        return env.Undefined();
    }
    
    Napi::Value GetValue(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        return Napi::Number::New(env, calculator_->GetValue());
    }
    
    Napi::Value Add(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 1 || !info[0].IsNumber()) {
            Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
            return Napi::Number::New(env, 0);
        }
        
        double operand = info[0].As<Napi::Number>().DoubleValue();
        double result = calculator_->Add(operand);
        
        return Napi::Number::New(env, result);
    }
    
    Napi::Value Multiply(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 1 || !info[0].IsNumber()) {
            Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
            return Napi::Number::New(env, 0);
        }
        
        double operand = info[0].As<Napi::Number>().DoubleValue();
        double result = calculator_->Multiply(operand);
        
        return Napi::Number::New(env, result);
    }
    
    Napi::Value Reset(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        calculator_->Reset();
        return env.Undefined();
    }
};

Napi::FunctionReference CalculatorWrapper::constructor;

主模块文件

cpp
// src/addon.cpp
#include <napi.h>

// 声明外部函数
Napi::Number Add(const Napi::CallbackInfo& info);
Napi::Number Fibonacci(const Napi::CallbackInfo& info);
Napi::Array VectorAdd(const Napi::CallbackInfo& info);
Napi::Array MatrixMultiply(const Napi::CallbackInfo& info);

Napi::String ReverseString(const Napi::CallbackInfo& info);
Napi::String CompressString(const Napi::CallbackInfo& info);
Napi::Number HashString(const Napi::CallbackInfo& info);
Napi::Array RegexMatch(const Napi::CallbackInfo& info);

Napi::Value ComputeAsync(const Napi::CallbackInfo& info);
Napi::Promise DelayedCompute(const Napi::CallbackInfo& info);

// 声明类包装器
class CalculatorWrapper;

// 模块初始化
Napi::Object Init(Napi::Env env, Napi::Object exports) {
    // 数学函数
    exports.Set(Napi::String::New(env, "add"), Napi::Function::New(env, Add));
    exports.Set(Napi::String::New(env, "fibonacci"), Napi::Function::New(env, Fibonacci));
    exports.Set(Napi::String::New(env, "vectorAdd"), Napi::Function::New(env, VectorAdd));
    exports.Set(Napi::String::New(env, "matrixMultiply"), Napi::Function::New(env, MatrixMultiply));
    
    // 字符串函数
    exports.Set(Napi::String::New(env, "reverseString"), Napi::Function::New(env, ReverseString));
    exports.Set(Napi::String::New(env, "compressString"), Napi::Function::New(env, CompressString));
    exports.Set(Napi::String::New(env, "hashString"), Napi::Function::New(env, HashString));
    exports.Set(Napi::String::New(env, "regexMatch"), Napi::Function::New(env, RegexMatch));
    
    // 异步函数
    exports.Set(Napi::String::New(env, "computeAsync"), Napi::Function::New(env, ComputeAsync));
    exports.Set(Napi::String::New(env, "delayedCompute"), Napi::Function::New(env, DelayedCompute));
    
    // 类绑定
    CalculatorWrapper::Init(env, exports);
    
    return exports;
}

NODE_API_MODULE(addon, Init)

📋 JavaScript使用示例

基础功能测试

javascript
// test.js - 测试原生模块
const addon = require('./build/Release/addon');

async function testBasicFunctions() {
    console.log('🧮 测试基础数学函数...');
    
    // 测试加法
    console.log('加法测试:', addon.add(5, 3)); // 8
    
    // 测试斐波那契
    console.log('斐波那契数列 F(10):', addon.fibonacci(10)); // 55
    
    // 测试向量加法
    const vector1 = [1, 2, 3, 4];
    const vector2 = [5, 6, 7, 8];
    console.log('向量加法:', addon.vectorAdd(vector1, vector2)); // [6, 8, 10, 12]
    
    // 测试矩阵乘法
    const matrix1 = [[1, 2], [3, 4]];
    const matrix2 = [[5, 6], [7, 8]];
    console.log('矩阵乘法:', addon.matrixMultiply(matrix1, matrix2)); // [[19, 22], [43, 50]]
}

async function testStringFunctions() {
    console.log('\n🔤 测试字符串处理函数...');
    
    // 测试字符串反转
    console.log('字符串反转:', addon.reverseString('Hello World')); // dlroW olleH
    
    // 测试字符串压缩
    console.log('字符串压缩:', addon.compressString('aaabbbcccdddd')); // a3b3c3d4
    
    // 测试字符串哈希
    console.log('字符串哈希:', addon.hashString('test string'));
    
    // 测试正则匹配
    console.log('正则匹配:', addon.regexMatch('hello123world456', '\\d+'));
}

async function testAsyncFunctions() {
    console.log('\n⚡ 测试异步函数...');
    
    // 测试回调式异步函数
    console.log('开始异步计算...');
    addon.computeAsync(1000000, (error, result) => {
        if (error) {
            console.error('异步计算错误:', error);
        } else {
            console.log('异步计算结果:', result);
        }
    });
    
    // 测试Promise式异步函数
    try {
        const result = await addon.delayedCompute(1000);
        console.log('延迟计算结果:', result);
    } catch (error) {
        console.error('延迟计算错误:', error);
    }
}

async function testCalculatorClass() {
    console.log('\n🏷️ 测试Calculator类...');
    
    const calc = new addon.Calculator();
    
    calc.setValue(10);
    console.log('初始值:', calc.getValue()); // 10
    
    console.log('加5:', calc.add(5)); // 15
    console.log('乘以2:', calc.multiply(2)); // 30
    console.log('当前值:', calc.getValue()); // 30
    
    calc.reset();
    console.log('重置后:', calc.getValue()); // 0
}

async function performanceBenchmark() {
    console.log('\n🚀 性能基准测试...');
    
    // JavaScript实现的斐波那契
    function fibJS(n) {
        if (n <= 1) return n;
        return fibJS(n - 1) + fibJS(n - 2);
    }
    
    const n = 35;
    
    // 测试JavaScript版本
    console.time('JavaScript斐波那契');
    const jsResult = fibJS(n);
    console.timeEnd('JavaScript斐波那契');
    console.log('JS结果:', jsResult);
    
    // 测试C++版本
    console.time('C++斐波那契');
    const cppResult = addon.fibonacci(n);
    console.timeEnd('C++斐波那契');
    console.log('C++结果:', cppResult);
    
    // 测试向量运算
    const largeVector1 = Array.from({ length: 100000 }, (_, i) => i);
    const largeVector2 = Array.from({ length: 100000 }, (_, i) => i * 2);
    
    console.time('C++向量加法');
    const vectorResult = addon.vectorAdd(largeVector1, largeVector2);
    console.timeEnd('C++向量加法');
    console.log('向量结果长度:', vectorResult.length);
    
    // 测试字符串处理
    const longString = 'a'.repeat(100000);
    
    console.time('C++字符串反转');
    const reversedString = addon.reverseString(longString);
    console.timeEnd('C++字符串反转');
    console.log('反转字符串长度:', reversedString.length);
}

// 运行所有测试
async function runAllTests() {
    try {
        await testBasicFunctions();
        await testStringFunctions();
        await testAsyncFunctions();
        await testCalculatorClass();
        
        // 等待异步操作完成
        await new Promise(resolve => setTimeout(resolve, 2000));
        
        await performanceBenchmark();
        
        console.log('\n✅ 所有测试完成!');
    } catch (error) {
        console.error('❌ 测试失败:', error);
    }
}

runAllTests();

构建脚本

javascript
// scripts/build.js - 自动化构建脚本
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

class AddonBuilder {
    constructor() {
        this.buildDir = path.join(__dirname, '..', 'build');
        this.srcDir = path.join(__dirname, '..', 'src');
    }
    
    checkDependencies() {
        console.log('🔍 检查构建依赖...');
        
        try {
            execSync('node-gyp --version', { stdio: 'ignore' });
            console.log('✅ node-gyp 已安装');
        } catch (error) {
            console.error('❌ node-gyp 未安装,请运行: npm install -g node-gyp');
            process.exit(1);
        }
        
        // 检查Python
        try {
            execSync('python --version', { stdio: 'ignore' });
            console.log('✅ Python 已安装');
        } catch (error) {
            console.warn('⚠️ Python 可能未安装或不在PATH中');
        }
        
        // 检查编译器
        const platform = process.platform;
        if (platform === 'win32') {
            console.log('📝 Windows平台:确保已安装Visual Studio Build Tools');
        } else if (platform === 'darwin') {
            try {
                execSync('xcode-select --version', { stdio: 'ignore' });
                console.log('✅ Xcode命令行工具已安装');
            } catch (error) {
                console.error('❌ 请安装Xcode命令行工具: xcode-select --install');
            }
        } else {
            console.log('🐧 Linux平台:确保已安装build-essential');
        }
    }
    
    clean() {
        console.log('🧹 清理构建目录...');
        
        if (fs.existsSync(this.buildDir)) {
            try {
                execSync('node-gyp clean', { stdio: 'inherit' });
                console.log('✅ 清理完成');
            } catch (error) {
                console.warn('⚠️ 清理时出现警告:', error.message);
            }
        }
    }
    
    configure() {
        console.log('⚙️ 配置构建环境...');
        
        try {
            execSync('node-gyp configure', { stdio: 'inherit' });
            console.log('✅ 配置完成');
        } catch (error) {
            console.error('❌ 配置失败:', error.message);
            process.exit(1);
        }
    }
    
    build() {
        console.log('🔨 开始编译...');
        
        try {
            execSync('node-gyp build', { stdio: 'inherit' });
            console.log('✅ 编译完成');
        } catch (error) {
            console.error('❌ 编译失败:', error.message);
            process.exit(1);
        }
    }
    
    rebuild() {
        console.log('🔄 重新构建...');
        
        try {
            execSync('node-gyp rebuild', { stdio: 'inherit' });
            console.log('✅ 重新构建完成');
        } catch (error) {
            console.error('❌ 重新构建失败:', error.message);
            process.exit(1);
        }
    }
    
    test() {
        console.log('🧪 运行测试...');
        
        const addonPath = path.join(this.buildDir, 'Release', 'addon.node');
        
        if (!fs.existsSync(addonPath)) {
            console.error('❌ 找不到编译后的addon文件');
            process.exit(1);
        }
        
        try {
            execSync('node test.js', { stdio: 'inherit' });
            console.log('✅ 测试完成');
        } catch (error) {
            console.error('❌ 测试失败:', error.message);
            process.exit(1);
        }
    }
    
    async fullBuild() {
        console.log('🚀 开始完整构建流程...\n');
        
        this.checkDependencies();
        this.clean();
        this.configure();
        this.build();
        this.test();
        
        console.log('\n🎉 构建流程完成!');
    }
}

// 命令行参数处理
const args = process.argv.slice(2);
const command = args[0] || 'full';

const builder = new AddonBuilder();

switch (command) {
    case 'clean':
        builder.clean();
        break;
    case 'configure':
        builder.configure();
        break;
    case 'build':
        builder.build();
        break;
    case 'rebuild':
        builder.rebuild();
        break;
    case 'test':
        builder.test();
        break;
    case 'full':
    default:
        builder.fullBuild();
        break;
}

C++ Addons为Node.js提供了强大的扩展能力,让我们能够在需要时获得原生代码的性能优势!