nodejs调用C++动态库

C++库源码

正常参数方法

arduino 复制代码
// 导出 C 接口函数,供外部调用
extern "C" __declspec(dllexport)
int GetCert(const char* input,unsigned char** output,unsigned int* outLen) {
    if (!input || !output || !outLen) { // 检查参数是否为 null
        return -1; // 参数错误
    }
    std::string result = "中文backData:"; // 创建字符串,初始化内容
    result += input; // 拼接输入参数 input 到 result
    int len = static_cast<int>(result.size()); // 获取 result 的长度
    // 分配内存,Node.js 要调用 CoTaskMemFree 释放
    unsigned   char* buffer = (unsigned  char*)CoTaskMemAlloc(len + 1); // 分配内存,+1 用于结尾符
    if (!buffer) { // 检查内存分配是否成功
        return -2; // 分配失败
    }
    //std::strcpy(buffer, result.c_str()); // 注释掉的代码,原本用于拷贝字符串
    int len2 = result.size(); // 获取 result 的长度
    unsigned char* udata2 = new unsigned char[len2 + 1]; // 分配新内存
    std::memcpy(udata2, result.c_str(), len2 + 1); // 拷贝字符串内容到新内存
    //strcpy_s(buffer, result.size() + 1, result.c_str()); // 注释掉的安全拷贝函数
    *output = udata2; // 设置输出参数 output 指向新内存
    *outLen = len2;   // 设置输出参数 outLen 为数据长度
    return 0; // 成功
}

指针参数的特殊方法

c 复制代码
// 导出 C 接口函数,供外部调用
extern "C" __declspec(dllexport)
int TransferToJS(const char* name, int age, int (*cb)(const char* str))    
{
    if (!cb || !name) { // 检查回调函数和 name 是否为 null
        return -1; // 参数错误
    }
    // 拼接字符串:例如 "name: 张三, age: 18"
    std::ostringstream oss; // 创建字符串流
    oss << "name: " << name << ", age: " << age; // 拼接 name 和 age
    std::string result = oss.str(); // 获取拼接后的字符串
    // 调用回调函数,传入拼接好的字符串
    return cb(result.c_str()); // 返回回调函数的返回值
}

nodejs 源码

正常参数方法

nodejs调用C++使用的是koffi库,代码如下.正常参数方法调用 ,正常调用getCert就可以调用C++方法

ini 复制代码
// 加载 DLL
    let libPath = path.resolve("./src/koffi/CertDll.dll");
    this.certLib = koffi.load(libPath);
    // 声明 C 函数:int GetCert(const char* input, char** output, int* outLen)
    this.GetCert = this.certLib.func(
      "int __stdcall GetCert(const char* input,_Out_  char** output,_Out_  int* outLen)"
    );
    
  getCert(certPath: string): string {
    // 准备输出参数(char** 和 int*)
    const outputPtr = koffi.alloc("char *", 1); // char**
    let buf = Buffer.alloc(1024);
    const outLenPtr = koffi.alloc("int", 1); // int*
    // const out1: any = koffi.out(koffi.pointer(koffi.types.int));
    // 调用 DLL 函数
    const ret = this.GetCert(certPath, buf, outLenPtr);
    if (ret === 0) {
      // 解引用输出
      const length = koffi.decode(outLenPtr, "int"); // int
      let ss = koffi.decode(buf, "char*", length);
      const charPtr = koffi.decode(outputPtr, "char*"); // char*
      return charPtr;
    } else {
      console.error("GetCert 调用失败,错误码:", ret);
      return "";
    }
  }

调用方法

arduino 复制代码
 ffiHelper.getCert("nihao!");

指针参数的特殊方法

调用指针方法,自己封装一个promise,把成功状态rev当做指针参数传入

typescript 复制代码
     // 定义 C 回调函数类型:void __stdcall(int)
    this.TransferCallback = koffi.proto(
      "int TransferCallback(const char *str, int age)"
    );
    this.TransferToJS = this.certLib.func("TransferToJS", "int", [
      "str",
      "int",
      koffi.pointer(this.TransferCallback),
    ]);

  async getStatus(name: string, age: number) {
    return new Promise((rev, rej) => {
      // 调用 DLL 函数,传入 JS 函数作为回调
      this.TransferToJS(name, age, rev);
    });
  }
}

调用指针方法

ini 复制代码
 let result = await koffiHelper.getStatus("niuhk", 18);

C++源码 nodejs源码

相关推荐
xiaoye-duck18 小时前
【C++:C++11】核心特性实战:详解C++11列表初始化、右值引用与移动语义
开发语言·c++·c++11
张小五31518 小时前
什么是node.js 小白也能看明白
node.js
睡一觉就好了。18 小时前
二叉搜索树
c++
whitelbwwww18 小时前
C++进阶--类和模板
c++
今天又在学代码写BUG口牙18 小时前
MFC 定时器轮询实现按住按钮进度条增加(鼠标悬停/长按检测)
c++·mfc·定时器·鼠标·轮询·长按事件
AIminminHu19 小时前
OpenGL渲染与几何内核那点事-项目实践理论补充(三-1-(3):番外篇-当你的CAD打开“怪兽级”STL时:从内存爆炸到零拷贝的极致优化)
开发语言·c++·线程·多线程
j_xxx404_19 小时前
力扣题型--链表(两数相加|两两交换链表中的节点|重排链表)
数据结构·c++·算法·leetcode·蓝桥杯·排序算法
kyle~19 小时前
FANUC 机械臂 --- 配置字
网络·c++·机器人·ros2
oldmao_200019 小时前
第八章 设计并发代码
开发语言·c++·多线程编程·并发编程
芒果披萨20 小时前
日志管理 logging
java·开发语言·c++