【发布时间】:2021-06-26 05:05:40
【问题描述】:
我正在尝试做一个简单的概念证明,并使用 ffi-napi 从节点调用一个非常基本的 c++ dll。
当我使用获取/返回 int 或 char 的方法时,它工作正常,但我返回字符串的尝试失败了。
c++代码,main.h:
#include <string>
#include <stdlib.h>
using namespace std;
#define EXPORT __declspec(dllexport)
extern "C" {
EXPORT string hello(string x);
EXPORT int count(int x);
}
c++代码,main.cpp:
#include "pch.h"
#include <string>
#include <stdlib.h>
#include "Main.h"
using namespace std;
string hello(string name)
{
return "Hello " + name + "! ";
}
int count(int x)
{
return x+1;
}
当我在下面运行节点代码时,
import { Console } from "node:console";
var ffi = require('ffi-napi');
var ref = require('ref-napi');
export class DllTester {
LibName: string = 'D:\\temp\\DemoDll\\x64\\Debug\\DemoDll.dll';
Lib: any = null;
private setupOcrLib()
{
this.Lib = ffi.Library(this.LibName,
{'hello': [ 'string', ['string']],
'count': [ ref.types.int, [ref.types.int]]
}
);
}
count(x: number): number {
this.setupOcrLib();
console.log("Calling count");
return this.Lib.count(x);
}
hello(name: string): string {
this.setupOcrLib();
console.log("Calling hello: " + name);
return this.Lib.hello(name);
}
}
const tester = new DllTester();
console.log("Count: " + tester.count(3));
console.log("Hello: " + tester.hello("Markus"));
console.log("Count: " + tester.count(10));
我得到以下控制台输出:
Calling count
Count: 4
Calling hello: Markus
所以第一次调用(发送 int,接收 int)工作正常,但第二次调用(发送字符串,接收字符串)静默失败并且 由于第二次调用 count 没有被记录,我相信我不成功的调用会扰乱流程。
尝试了以下方法:
- 在 dll 中使用 char* 而不是字符串。然后我收到“东西”但不可读的文本
- 使用 ref-napi 设置类型而不是字符串,但演示表明这不是必需的:https://github.com/node-ffi-napi/node-ffi-napi
我对 c++ 的理解有限,可能遗漏了一些关于类型和指针的部分,但这看起来很简单,应该不会出错...
平台:windows 10, 64 bit, node v14.12.0, VS 2019 Community
版本: "ffi-napi": "^4.0.3", "ref-napi": "^3.0.2"
感谢您的意见 :-)
【问题讨论】:
-
您是否尝试过使用
std::string?在 JS 方面,没有什么类似于 C++ 方面的using namespace std;的操作。顺便说一句:在 C++ 中这样做是不受欢迎的,因为它会污染命名空间,但这是一个不同的问题。 -
在 DLL 甚至不同语言之间编组字符串的传统方式是客户端创建一个缓冲区,然后客户端将该缓冲区发送到 DLL 以填充字符数据。
std::string不是通用的内置类型,例如int。std::string内部在 C++ 编译器、构建设置等方面有所不同。如果您想要一个真实的示例,请查看 Windows API 以及它如何处理字符串数据。用户创建缓冲区,将其发送到 API 函数,函数填充缓冲区。 -
@UlrichEckhardt 在“双方”都试过了。仅在 c++ 端使用它会得到与以前相同的结果,如果我在 typescript 中尝试它,我会收到错误:无法确定正确的“类型”来自:'std::string' 还尝试在 c++ 端使用 CString ,也没有用。感谢您的意见!
-
@PaulMcKenzie 好的,所以我不应该期望这么容易返回一个字符串?所以我想我应该发送一个指向我的方法的指针而不是使用返回值。你在使用 ffi 之前做过这个吗?希望看到一个如何处理字符串的代码示例。谢谢!
标签: c++ node.js node-modules ffi