Skip to content

N-API使用

🎯 学习目标

  • 理解N-API的优势和应用场景
  • 掌握N-API的基本使用方法
  • 学会使用node-addon-api简化开发
  • 了解N-API的最佳实践和性能优化

📚 核心概念

N-API简介

javascript
// N-API的主要特性
const napiFeatures = {
  abiStability: {
    description: 'ABI稳定性',
    benefits: [
      '跨Node.js版本兼容',
      '无需重新编译',
      '减少维护成本',
      '提高发布效率'
    ]
  },
  cInterface: {
    description: 'C语言接口',
    benefits: [
      '语言无关性',
      '更好的稳定性',
      '减少V8依赖',
      '长期支持保证'
    ]
  },
  performance: {
    description: '性能优化',
    benefits: [
      '减少类型转换开销',
      '优化内存使用',
      '更好的错误处理',
      '异步操作支持'
    ]
  }
};

console.log('N-API特性:', napiFeatures);

环境配置

json
// package.json - N-API项目配置
{
  "name": "napi-example",
  "version": "1.0.0",
  "description": "N-API使用示例",
  "main": "index.js",
  "scripts": {
    "build": "node-gyp rebuild",
    "clean": "node-gyp clean",
    "test": "node test.js",
    "install": "node-gyp rebuild"
  },
  "dependencies": {
    "node-addon-api": "^5.0.0"
  },
  "devDependencies": {
    "node-gyp": "^9.0.0"
  },
  "binary": {
    "napi_versions": [3, 4, 5, 6, 7, 8]
  }
}
python
# binding.gyp - N-API构建配置
{
  "targets": [
    {
      "target_name": "napi_addon",
      "sources": [
        "src/main.cpp",
        "src/basic_types.cpp",
        "src/async_operations.cpp",
        "src/object_wrap.cpp",
        "src/error_handling.cpp"
      ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include\")"
      ],
      "defines": [
        "NAPI_DISABLE_CPP_EXCEPTIONS"
      ],
      "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 }
      }
    }
  ]
}

🛠️ 基础类型处理

数值类型操作

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

// 数值运算函数
Napi::Value AddNumbers(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    // 参数验证
    if (info.Length() < 2) {
        Napi::TypeError::New(env, "Expected at least 2 arguments").ThrowAsJavaScriptException();
        return env.Null();
    }
    
    if (!info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Expected numbers").ThrowAsJavaScriptException();
        return env.Null();
    }
    
    // 获取数值
    double num1 = info[0].As<Napi::Number>().DoubleValue();
    double num2 = info[1].As<Napi::Number>().DoubleValue();
    
    // 执行运算
    double result = num1 + num2;
    
    return Napi::Number::New(env, result);
}

// 数学运算集合
Napi::Object MathOperations(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Expected two numbers").ThrowAsJavaScriptException();
        return Napi::Object::New(env);
    }
    
    double a = info[0].As<Napi::Number>().DoubleValue();
    double b = info[1].As<Napi::Number>().DoubleValue();
    
    // 创建结果对象
    Napi::Object result = Napi::Object::New(env);
    
    result.Set("add", Napi::Number::New(env, a + b));
    result.Set("subtract", Napi::Number::New(env, a - b));
    result.Set("multiply", Napi::Number::New(env, a * b));
    
    if (b != 0) {
        result.Set("divide", Napi::Number::New(env, a / b));
    } else {
        result.Set("divide", env.Null());
    }
    
    result.Set("power", Napi::Number::New(env, std::pow(a, b)));
    result.Set("max", Napi::Number::New(env, std::max(a, b)));
    result.Set("min", Napi::Number::New(env, std::min(a, b)));
    
    return result;
}

// 数组处理
Napi::Value ProcessArray(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 1 || !info[0].IsArray()) {
        Napi::TypeError::New(env, "Expected an array").ThrowAsJavaScriptException();
        return env.Null();
    }
    
    Napi::Array inputArray = info[0].As<Napi::Array>();
    uint32_t length = inputArray.Length();
    
    // 创建结果数组
    Napi::Array resultArray = Napi::Array::New(env, length);
    
    double sum = 0.0;
    double max = -INFINITY;
    double min = INFINITY;
    
    for (uint32_t i = 0; i < length; i++) {
        Napi::Value element = inputArray.Get(i);
        
        if (element.IsNumber()) {
            double value = element.As<Napi::Number>().DoubleValue();
            
            // 计算平方
            double squared = value * value;
            resultArray.Set(i, Napi::Number::New(env, squared));
            
            // 统计信息
            sum += value;
            max = std::max(max, value);
            min = std::min(min, value);
        } else {
            resultArray.Set(i, env.Null());
        }
    }
    
    // 创建包含统计信息的结果对象
    Napi::Object result = Napi::Object::New(env);
    result.Set("squared", resultArray);
    result.Set("sum", Napi::Number::New(env, sum));
    result.Set("average", Napi::Number::New(env, sum / length));
    result.Set("max", Napi::Number::New(env, max));
    result.Set("min", Napi::Number::New(env, min));
    
    return result;
}

字符串处理

cpp
// 字符串操作函数
Napi::Value StringOperations(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 env.Null();
    }
    
    std::string input = info[0].As<Napi::String>().Utf8Value();
    
    // 创建结果对象
    Napi::Object result = Napi::Object::New(env);
    
    // 长度
    result.Set("length", Napi::Number::New(env, input.length()));
    
    // 大写转换
    std::string uppercase = input;
    std::transform(uppercase.begin(), uppercase.end(), uppercase.begin(), ::toupper);
    result.Set("uppercase", Napi::String::New(env, uppercase));
    
    // 小写转换
    std::string lowercase = input;
    std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(), ::tolower);
    result.Set("lowercase", Napi::String::New(env, lowercase));
    
    // 反转
    std::string reversed = input;
    std::reverse(reversed.begin(), reversed.end());
    result.Set("reversed", Napi::String::New(env, reversed));
    
    // 字符统计
    std::map<char, int> charCount;
    for (char c : input) {
        charCount[c]++;
    }
    
    Napi::Object charStats = Napi::Object::New(env);
    for (const auto& pair : charCount) {
        std::string key(1, pair.first);
        charStats.Set(key, Napi::Number::New(env, pair.second));
    }
    result.Set("charCount", charStats);
    
    return result;
}

// UTF-8字符串处理
Napi::Value Utf8StringInfo(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 env.Null();
    }
    
    Napi::String jsString = info[0].As<Napi::String>();
    
    // 获取不同编码的长度
    size_t utf8Length = jsString.Utf8Value().length();
    size_t utf16Length = jsString.Utf16Value().length();
    
    Napi::Object result = Napi::Object::New(env);
    result.Set("utf8Length", Napi::Number::New(env, utf8Length));
    result.Set("utf16Length", Napi::Number::New(env, utf16Length));
    result.Set("jsLength", Napi::Number::New(env, jsString.As<Napi::String>().Utf8Value().length()));
    
    // 字节数组
    std::string utf8Str = jsString.Utf8Value();
    Napi::Array byteArray = Napi::Array::New(env, utf8Str.length());
    
    for (size_t i = 0; i < utf8Str.length(); i++) {
        byteArray.Set(i, Napi::Number::New(env, static_cast<unsigned char>(utf8Str[i])));
    }
    
    result.Set("bytes", byteArray);
    
    return result;
}

⚡ 异步操作处理

异步Worker实现

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

// 基础异步Worker
class BasicAsyncWorker : public Napi::AsyncWorker {
public:
    BasicAsyncWorker(Napi::Function& callback, int workload)
        : Napi::AsyncWorker(callback), workload_(workload), result_(0) {}
    
    ~BasicAsyncWorker() {}
    
    // 在工作线程中执行
    void Execute() override {
        try {
            // 模拟CPU密集型任务
            double sum = 0.0;
            for (int i = 0; i < workload_; i++) {
                sum += std::sin(i) * std::cos(i);
                
                // 检查取消状态
                if (this->IsCancelled()) {
                    SetError("Operation was cancelled");
                    return;
                }
                
                // 定期让出CPU
                if (i % 10000 == 0) {
                    std::this_thread::sleep_for(std::chrono::microseconds(1));
                }
            }
            result_ = sum;
        } catch (const std::exception& e) {
            SetError(e.what());
        }
    }
    
    // 在主线程中处理结果
    void OnOK() override {
        Napi::HandleScope scope(Env());
        
        // 创建结果对象
        Napi::Object result = Napi::Object::New(Env());
        result.Set("value", Napi::Number::New(Env(), result_));
        result.Set("workload", Napi::Number::New(Env(), workload_));
        
        Callback().Call({Env().Null(), result});
    }
    
    void OnError(const Napi::Error& e) override {
        Napi::HandleScope scope(Env());
        Callback().Call({e.Value(), Env().Undefined()});
    }

private:
    int workload_;
    double result_;
};

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

// Promise-based异步操作
class PromiseAsyncWorker : public Napi::AsyncWorker {
public:
    PromiseAsyncWorker(Napi::Env env, int delay)
        : Napi::AsyncWorker(env), delay_(delay), deferred_(Napi::Promise::Deferred::New(env)) {}
    
    ~PromiseAsyncWorker() {}
    
    void Execute() override {
        // 模拟异步I/O操作
        std::this_thread::sleep_for(std::chrono::milliseconds(delay_));
        
        // 模拟一些计算
        result_ = delay_ * 1.5 + std::rand() % 100;
    }
    
    void OnOK() override {
        Napi::Object result = Napi::Object::New(Env());
        result.Set("value", Napi::Number::New(Env(), result_));
        result.Set("delay", Napi::Number::New(Env(), delay_));
        result.Set("timestamp", Napi::Number::New(Env(), std::time(nullptr)));
        
        deferred_.Resolve(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 AsyncWithPromise(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();
    
    PromiseAsyncWorker* worker = new PromiseAsyncWorker(env, delay);
    Napi::Promise promise = worker->GetPromise();
    worker->Queue();
    
    return promise;
}

// 批量异步操作
class BatchAsyncWorker : public Napi::AsyncWorker {
public:
    BatchAsyncWorker(Napi::Function& callback, std::vector<int> tasks)
        : Napi::AsyncWorker(callback), tasks_(std::move(tasks)) {}
    
    ~BatchAsyncWorker() {}
    
    void Execute() override {
        results_.reserve(tasks_.size());
        
        // 并行处理任务
        std::vector<std::future<double>> futures;
        futures.reserve(tasks_.size());
        
        for (int task : tasks_) {
            futures.emplace_back(std::async(std::launch::async, [task]() {
                // 模拟任务处理
                std::this_thread::sleep_for(std::chrono::milliseconds(task % 100));
                return static_cast<double>(task * task);
            }));
        }
        
        // 收集结果
        for (auto& future : futures) {
            if (this->IsCancelled()) {
                SetError("Batch operation was cancelled");
                return;
            }
            
            try {
                results_.push_back(future.get());
            } catch (const std::exception& e) {
                SetError(e.what());
                return;
            }
        }
    }
    
    void OnOK() override {
        Napi::HandleScope scope(Env());
        
        Napi::Array resultArray = Napi::Array::New(Env(), results_.size());
        for (size_t i = 0; i < results_.size(); i++) {
            resultArray.Set(i, Napi::Number::New(Env(), results_[i]));
        }
        
        Napi::Object result = Napi::Object::New(Env());
        result.Set("results", resultArray);
        result.Set("count", Napi::Number::New(Env(), results_.size()));
        
        Callback().Call({Env().Null(), result});
    }
    
    void OnError(const Napi::Error& e) override {
        Napi::HandleScope scope(Env());
        Callback().Call({e.Value(), Env().Undefined()});
    }

private:
    std::vector<int> tasks_;
    std::vector<double> results_;
};

// 批量异步处理函数
Napi::Value ProcessBatchAsync(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    if (info.Length() < 2) {
        Napi::TypeError::New(env, "Expected array and callback").ThrowAsJavaScriptException();
        return env.Undefined();
    }
    
    if (!info[0].IsArray() || !info[1].IsFunction()) {
        Napi::TypeError::New(env, "Invalid arguments").ThrowAsJavaScriptException();
        return env.Undefined();
    }
    
    Napi::Array tasksArray = info[0].As<Napi::Array>();
    Napi::Function callback = info[1].As<Napi::Function>();
    
    // 转换任务数组
    std::vector<int> tasks;
    uint32_t length = tasksArray.Length();
    tasks.reserve(length);
    
    for (uint32_t i = 0; i < length; i++) {
        Napi::Value element = tasksArray.Get(i);
        if (element.IsNumber()) {
            tasks.push_back(element.As<Napi::Number>().Int32Value());
        }
    }
    
    BatchAsyncWorker* worker = new BatchAsyncWorker(callback, std::move(tasks));
    worker->Queue();
    
    return env.Undefined();
}

🏷️ 对象包装和类绑定

复杂对象包装

cpp
// src/object_wrap.cpp
#include <napi.h>
#include <memory>
#include <vector>
#include <map>
#include <string>

// 原生C++数据结构
class DataProcessor {
public:
    DataProcessor(const std::string& name) : name_(name), processed_count_(0) {}
    
    void AddData(const std::string& key, double value) {
        data_[key] = value;
    }
    
    double GetData(const std::string& key) const {
        auto it = data_.find(key);
        return it != data_.end() ? it->second : 0.0;
    }
    
    std::vector<std::string> GetKeys() const {
        std::vector<std::string> keys;
        for (const auto& pair : data_) {
            keys.push_back(pair.first);
        }
        return keys;
    }
    
    double ProcessData(const std::string& operation) {
        processed_count_++;
        
        if (operation == "sum") {
            double sum = 0.0;
            for (const auto& pair : data_) {
                sum += pair.second;
            }
            return sum;
        } else if (operation == "average") {
            if (data_.empty()) return 0.0;
            double sum = ProcessData("sum");
            return sum / data_.size();
        } else if (operation == "max") {
            if (data_.empty()) return 0.0;
            double max_val = data_.begin()->second;
            for (const auto& pair : data_) {
                max_val = std::max(max_val, pair.second);
            }
            return max_val;
        }
        
        return 0.0;
    }
    
    void Clear() {
        data_.clear();
    }
    
    size_t Size() const {
        return data_.size();
    }
    
    const std::string& GetName() const {
        return name_;
    }
    
    int GetProcessedCount() const {
        return processed_count_;
    }

private:
    std::string name_;
    std::map<std::string, double> data_;
    int processed_count_;
};

// Node.js包装类
class DataProcessorWrapper : public Napi::ObjectWrap<DataProcessorWrapper> {
public:
    static Napi::Object Init(Napi::Env env, Napi::Object exports) {
        Napi::HandleScope scope(env);
        
        Napi::Function func = DefineClass(env, "DataProcessor", {
            InstanceMethod("addData", &DataProcessorWrapper::AddData),
            InstanceMethod("getData", &DataProcessorWrapper::GetData),
            InstanceMethod("getKeys", &DataProcessorWrapper::GetKeys),
            InstanceMethod("processData", &DataProcessorWrapper::ProcessData),
            InstanceMethod("clear", &DataProcessorWrapper::Clear),
            InstanceMethod("size", &DataProcessorWrapper::Size),
            InstanceAccessor("name", &DataProcessorWrapper::GetName, nullptr),
            InstanceAccessor("processedCount", &DataProcessorWrapper::GetProcessedCount, nullptr)
        });
        
        constructor = Napi::Persistent(func);
        constructor.SuppressDestruct();
        
        exports.Set("DataProcessor", func);
        return exports;
    }
    
    DataProcessorWrapper(const Napi::CallbackInfo& info) 
        : Napi::ObjectWrap<DataProcessorWrapper>(info) {
        Napi::Env env = info.Env();
        Napi::HandleScope scope(env);
        
        if (info.Length() < 1 || !info[0].IsString()) {
            Napi::TypeError::New(env, "Expected a string name").ThrowAsJavaScriptException();
            return;
        }
        
        std::string name = info[0].As<Napi::String>().Utf8Value();
        processor_ = std::make_unique<DataProcessor>(name);
    }

private:
    static Napi::FunctionReference constructor;
    std::unique_ptr<DataProcessor> processor_;
    
    Napi::Value AddData(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 2 || !info[0].IsString() || !info[1].IsNumber()) {
            Napi::TypeError::New(env, "Expected string key and number value").ThrowAsJavaScriptException();
            return env.Undefined();
        }
        
        std::string key = info[0].As<Napi::String>().Utf8Value();
        double value = info[1].As<Napi::Number>().DoubleValue();
        
        processor_->AddData(key, value);
        
        return env.Undefined();
    }
    
    Napi::Value GetData(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 1 || !info[0].IsString()) {
            Napi::TypeError::New(env, "Expected a string key").ThrowAsJavaScriptException();
            return env.Null();
        }
        
        std::string key = info[0].As<Napi::String>().Utf8Value();
        double value = processor_->GetData(key);
        
        return Napi::Number::New(env, value);
    }
    
    Napi::Value GetKeys(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        std::vector<std::string> keys = processor_->GetKeys();
        Napi::Array result = Napi::Array::New(env, keys.size());
        
        for (size_t i = 0; i < keys.size(); i++) {
            result.Set(i, Napi::String::New(env, keys[i]));
        }
        
        return result;
    }
    
    Napi::Value ProcessData(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        
        if (info.Length() < 1 || !info[0].IsString()) {
            Napi::TypeError::New(env, "Expected operation name").ThrowAsJavaScriptException();
            return env.Null();
        }
        
        std::string operation = info[0].As<Napi::String>().Utf8Value();
        double result = processor_->ProcessData(operation);
        
        return Napi::Number::New(env, result);
    }
    
    Napi::Value Clear(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        processor_->Clear();
        return env.Undefined();
    }
    
    Napi::Value Size(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        return Napi::Number::New(env, processor_->Size());
    }
    
    Napi::Value GetName(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        return Napi::String::New(env, processor_->GetName());
    }
    
    Napi::Value GetProcessedCount(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        return Napi::Number::New(env, processor_->GetProcessedCount());
    }
};

Napi::FunctionReference DataProcessorWrapper::constructor;

🔧 错误处理和调试

完善的错误处理

cpp
// src/error_handling.cpp
#include <napi.h>
#include <stdexcept>

// 自定义错误类型
class CustomError : public std::runtime_error {
public:
    CustomError(const std::string& message, int code) 
        : std::runtime_error(message), code_(code) {}
    
    int GetCode() const { return code_; }

private:
    int code_;
};

// 安全的除法运算
Napi::Value SafeDivide(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    try {
        // 参数验证
        if (info.Length() < 2) {
            throw std::invalid_argument("Expected 2 arguments");
        }
        
        if (!info[0].IsNumber() || !info[1].IsNumber()) {
            throw std::invalid_argument("Arguments must be numbers");
        }
        
        double dividend = info[0].As<Napi::Number>().DoubleValue();
        double divisor = info[1].As<Napi::Number>().DoubleValue();
        
        // 除零检查
        if (divisor == 0.0) {
            throw CustomError("Division by zero", 1001);
        }
        
        // 溢出检查
        if (std::abs(dividend) > 1e308 || std::abs(divisor) < 1e-308) {
            throw CustomError("Potential overflow", 1002);
        }
        
        double result = dividend / divisor;
        
        // 结果验证
        if (!std::isfinite(result)) {
            throw CustomError("Result is not finite", 1003);
        }
        
        return Napi::Number::New(env, result);
        
    } catch (const CustomError& e) {
        // 创建自定义错误对象
        Napi::Object error = Napi::Object::New(env);
        error.Set("name", Napi::String::New(env, "CustomError"));
        error.Set("message", Napi::String::New(env, e.what()));
        error.Set("code", Napi::Number::New(env, e.GetCode()));
        
        Napi::Error::New(env, error.As<Napi::String>()).ThrowAsJavaScriptException();
        return env.Null();
        
    } catch (const std::invalid_argument& e) {
        Napi::TypeError::New(env, e.what()).ThrowAsJavaScriptException();
        return env.Null();
        
    } catch (const std::exception& e) {
        Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
        return env.Null();
        
    } catch (...) {
        Napi::Error::New(env, "Unknown error occurred").ThrowAsJavaScriptException();
        return env.Null();
    }
}

// 资源管理示例
class ResourceManager {
public:
    ResourceManager() : resource_(nullptr) {}
    
    ~ResourceManager() {
        Cleanup();
    }
    
    bool Initialize() {
        try {
            resource_ = new int[1000000]; // 分配大量内存
            return true;
        } catch (const std::bad_alloc&) {
            return false;
        }
    }
    
    void Cleanup() {
        delete[] resource_;
        resource_ = nullptr;
    }
    
    bool IsValid() const {
        return resource_ != nullptr;
    }

private:
    int* resource_;
};

// RAII资源管理函数
Napi::Value ManageResource(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    try {
        ResourceManager manager;
        
        if (!manager.Initialize()) {
            throw std::runtime_error("Failed to initialize resource");
        }
        
        // 模拟一些操作
        if (info.Length() > 0 && info[0].IsBoolean() && info[0].As<Napi::Boolean>().Value()) {
            throw std::runtime_error("Simulated operation failure");
        }
        
        // 资源会在manager析构时自动清理
        return Napi::Boolean::New(env, true);
        
    } catch (const std::exception& e) {
        Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
        return Napi::Boolean::New(env, false);
    }
}

// 调试信息收集
Napi::Object GetDebugInfo(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    
    Napi::Object debugInfo = Napi::Object::New(env);
    
    // 编译信息
    debugInfo.Set("compiler", Napi::String::New(env, 
#ifdef __GNUC__
        "GCC " __VERSION__
#elif defined(_MSC_VER)
        "MSVC"
#elif defined(__clang__)
        "Clang " __clang_version__
#else
        "Unknown"
#endif
    ));
    
    // 平台信息
    debugInfo.Set("platform", Napi::String::New(env,
#ifdef _WIN32
        "Windows"
#elif defined(__linux__)
        "Linux"
#elif defined(__APPLE__)
        "macOS"
#else
        "Unknown"
#endif
    ));
    
    // 架构信息
    debugInfo.Set("architecture", Napi::String::New(env,
#ifdef _WIN64
        "x64"
#elif defined(_WIN32)
        "x86"
#elif defined(__x86_64__)
        "x64"
#elif defined(__i386__)
        "x86"
#elif defined(__aarch64__)
        "arm64"
#else
        "Unknown"
#endif
    ));
    
    // N-API版本
    uint32_t napi_version;
    napi_status status = napi_get_version(env, &napi_version);
    if (status == napi_ok) {
        debugInfo.Set("napiVersion", Napi::Number::New(env, napi_version));
    }
    
    return debugInfo;
}

主模块集成

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

// 声明所有函数
Napi::Value AddNumbers(const Napi::CallbackInfo& info);
Napi::Object MathOperations(const Napi::CallbackInfo& info);
Napi::Value ProcessArray(const Napi::CallbackInfo& info);
Napi::Value StringOperations(const Napi::CallbackInfo& info);
Napi::Value Utf8StringInfo(const Napi::CallbackInfo& info);

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

Napi::Value SafeDivide(const Napi::CallbackInfo& info);
Napi::Value ManageResource(const Napi::CallbackInfo& info);
Napi::Object GetDebugInfo(const Napi::CallbackInfo& info);

// 声明类包装器
class DataProcessorWrapper;

// 模块初始化
Napi::Object Init(Napi::Env env, Napi::Object exports) {
    // 基础类型操作
    exports.Set("addNumbers", Napi::Function::New(env, AddNumbers));
    exports.Set("mathOperations", Napi::Function::New(env, MathOperations));
    exports.Set("processArray", Napi::Function::New(env, ProcessArray));
    exports.Set("stringOperations", Napi::Function::New(env, StringOperations));
    exports.Set("utf8StringInfo", Napi::Function::New(env, Utf8StringInfo));
    
    // 异步操作
    exports.Set("computeAsync", Napi::Function::New(env, ComputeAsync));
    exports.Set("asyncWithPromise", Napi::Function::New(env, AsyncWithPromise));
    exports.Set("processBatchAsync", Napi::Function::New(env, ProcessBatchAsync));
    
    // 错误处理
    exports.Set("safeDivide", Napi::Function::New(env, SafeDivide));
    exports.Set("manageResource", Napi::Function::New(env, ManageResource));
    exports.Set("getDebugInfo", Napi::Function::New(env, GetDebugInfo));
    
    // 类绑定
    DataProcessorWrapper::Init(env, exports);
    
    return exports;
}

NODE_API_MODULE(napi_addon, Init)

N-API为Node.js原生模块开发提供了稳定、高效的接口,是构建高性能扩展的理想选择!