C++库源码

正常参数方法

// 导出 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 接口函数,供外部调用
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++方法

// 加载 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 "";
    }
  }

调用方法

 ffiHelper.getCert("nihao!");

指针参数的特殊方法

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

     // 定义 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);
    });
  }
}

调用指针方法

 let result = await koffiHelper.getStatus("niuhk", 18);

C++源码 nodejs源码

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]