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源码

相关推荐
aaPIXa62243 分钟前
C++ 用 13 条规则让模型写出安全现代 C++
java·c++·安全
孟陬2 小时前
高质量全方位的 AI 工具 sse-stuntman — Mock SSE 接口
前端·node.js·openai
枕星而眠2 小时前
【数据结构】红黑树入门指南
运维·数据结构·c++·后端
掰头战士2 小时前
你本地的LLM有时会胡乱使用tools?不妨用MCP规范LLM工具调用!
node.js·llm·全栈
2601_949817722 小时前
C++指针与引用深度精讲:底层原理、差异对比与高阶实战陷阱
java·jvm·c++
触底反弹2 小时前
🧠 LangChain Agent 入门:为什么直接调大模型 API 远远不够?
人工智能·node.js·llm
书中枫叶3 小时前
从「上次几点喂奶」到全栈小程序:我做了个喂宝助手
mongodb·微信小程序·node.js
烟锁池塘柳04 小时前
【C/C++】解决C++控制台输出中文乱码问题
c语言·开发语言·c++
zh路西法4 小时前
【10天速通Navigation2】(九):LQR最优控制器的原理推导与Nav2插件实现
c++·ros2·最优控制·lqr·navigation2
粘稠的浆糊4 小时前
[AtCoder - abc465_d ]X to Y题解
数据结构·c++·算法