策马守天关苹果版
262.6M · 2025-10-22
// 导出 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调用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源码