node-addon-api + CMake + 调用动态库

本文介绍了如何使用CMake和node-addon-api在Windows环境下构建Node.js的原生模块。通过示例展示了从package.json配置到CMakeLists.txt的编写,以及源代码的实现。示例中包含了对N-API的使用,以及如何在C++中调用Node.js的API。此外,还提到了线程安全函数的使用参考。
摘要由CSDN通过智能技术生成

node-addon-api + CMake

概述

node-addon-api 独立于V8,上手简单了。作为官方API的存在,质量有保证。同时版本适配问题比较友好。


本文参考了Node.js Addon Examples中的以下2个例子

  1. build_with_cmake
  2. 6_object_wrap

环境

Window 10
nodejs 16.14.2 (Currently using 64-bit executable)

依赖

node-addon-api 4.3.0
cmake-js 6.3.0

栗子

修改 package.json ,在script中添加以下内容

"scripts": {
    "install": "cmake-js compile"
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.9)
cmake_policy(SET CMP0042 NEW)
set (CMAKE_CXX_STANDARD 11)

project (test_project)
set(VERSION 1.0.0.0)
SET(CMAKE_CXX_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")

if (MSVC)
    set(CMAKE_DEBUG_POSTFIX _d)
endif ()

find_package(JThread REQUIRED)
find_package(JRTPLIB REQUIRED)

set(NODE_LINK_LIBS "")
set(NODE_EXTERNAL_INCLUDES "")

include_directories(${CMAKE_JS_INC})
include_directories(${JTHREAD_INCLUDE_DIRS} ${JRTPLIB_INCLUDE_DIRS})

file(GLOB HEADER_FILES 
"src/index.h")

file(GLOB SOURCE_FILES 
"src/index.cc" 
"src/export.cc")

add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")

target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ${JTHREAD_LIBRARIES} ${JRTPLIB_LIBRARIES})

# Include Node-API wrappers
execute_process(COMMAND node -p "require('node-addon-api').include"
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        OUTPUT_VARIABLE NODE_ADDON_API_DIR
        )
string(REGEX REPLACE "[\r\n\"]" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})

target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR})

# define NPI_VERSION
add_definitions(-DNAPI_VERSION=8)
add_definitions(-DNAPI_DISABLE_CPP_EXCEPTIONS)

index.h

#ifndef INDEX_H
#define INDEX_H

#include <napi.h>

class IndexM : public Napi::ObjectWrap<IndexM>{
public:
    //导出函数
    static Napi::Object Init(Napi::Env env, Napi::Object exports);
    static Napi::FunctionReference constructor;
    
    IndexM(const Napi::CallbackInfo& info);

    Napi::Value getValue(const Napi::CallbackInfo& info);
    void setValue(const Napi::CallbackInfo& info);

private:
    int m_value = 0;
};

#endif

index.cc

#include "index.h"

Napi::FunctionReference IndexM::constructor;

Napi::Object IndexM::Init(Napi::Env env, Napi::Object exports)
{
    Napi::HandleScope scope(env);

    Napi::Function func =
        DefineClass(env,
                    "IndexM",
                    {
                        InstanceMethod("getValue", &IndexM::getValue),
                        InstanceMethod("setValue", &IndexM::setValue),
                    });

    constructor = Napi::Persistent(func);
    constructor.SuppressDestruct();

    exports.Set("IndexM", func);
    return exports;
}

IndexM::IndexM(const Napi::CallbackInfo& info) : Napi::ObjectWrap<IndexM>(info)
{
}

Napi::Value IndexM::getValue(const Napi::CallbackInfo& info)
{
    return Napi::Number::New(info.Env(),m_value);
}

void IndexM::setValue(const Napi::CallbackInfo& info)
{
    int len = info.Length();
    
    Napi::Env env = info.Env();

    if (len <= 0 || !info[0].IsNumber()) {
        Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
    }

    Napi::Number value = info[0].As<Napi::Number>();
    m_value = value.Int32Value();
}

export.cc

#include "index.h"

//导出接口
Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
  return IndexM::Init(env, exports);
}

NODE_API_MODULE(IndexM, InitAll)

温馨提示:

对了有个例子是线程中,调用JS回调的 typed_threadsafe_function

参考

node-addon-api GitHub

Node.js API中文网

node-addon-api 简单案例和介绍

全是案例:Node.js Addon Examples

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值