Nodejs 如何使用 通过ffi调用返回来的内存指针

Nodejs 如何使用 通过ffi调用返回来的内存指针

nodejs封装了一个c库 通过c库返回来一个内存指针,但数据不知道如何读出来,请高手帮解答下 代码片如下: uint8_t = ref.types.uint8; var uint8_ptr = ref.refType(uint8_t); var Struct = require(‘ref-struct’); var pic_t = Struct( { data:uint8_ptr, linesize:‘int’, pts:int64_t, dts:int64_t, duration:‘int’ } ); var picptr = ref.refType(pic_t); 通过调用c库的回调会返回一个picptr的对象,通过 var picture = pic.deref(); var data = picture.data0; console.log(‘canvas render one frame, pts’+ picture.pts); 可以正确的获取picture中的pts成员的值, 但要如何获取data呢,data是一个uint8* 指针 现在的问题是如何将data中的值读出来 将data作为数组,data[1]就是undefined 谢谢!


10 回复

在Node.js中使用ffi(Foreign Function Interface)调用C库并处理返回的内存指针时,常常需要对这些指针进行解引用以访问实际的数据。在你的例子中,你遇到了如何正确读取data字段中的数据的问题。下面将提供一个详细的解决方案,并附带一些示例代码。

首先,我们需要确保安装了必要的库:

npm install ffi-napi ref-napi ref-struct-napi

接下来,我们从你的问题中提取关键部分,并提供完整的代码实现。

示例代码

假设你有一个C库,它返回一个包含图像数据的结构体指针。你需要解析这个结构体并访问其中的数据。

C库函数原型(假设)

typedef struct {
    uint8_t *data;
    int linesize;
    int64_t pts;
    int64_t dts;
    int duration;
} Picture;

Picture *get_picture();

Node.js 代码

const ffi = require('ffi-napi');
const ref = require('ref-napi');
const Struct = require('ref-struct-napi');

// 定义类型
const uint8_t = ref.types.uint8;
const int = ref.types.int;
const int64_t = ref.types.int64;

// 定义结构体
const PictureStruct = Struct({
    data: ref.refType(uint8_t),
    linesize: int,
    pts: int64_t,
    dts: int64_t,
    duration: int
});

// 加载C库
const lib = new ffi.Library('./path/to/lib', {
    get_picture: [PictureStruct, []]
});

// 调用C函数
const picture = lib.get_picture();

// 解引用data指针
const dataPtr = picture.data.deref();
const dataSize = picture.linesize;

// 将数据转换为Buffer以便访问
const dataBuffer = new Buffer(dataSize);
for (let i = 0; i < dataSize; i++) {
    dataBuffer[i] = dataPtr.readUInt8(i);
}

// 打印结果
console.log(`Canvas render one frame, pts: ${picture.pts}, data:`, dataBuffer);

解释

  1. 定义类型:首先定义所有使用的C语言类型。
  2. 结构体定义:使用ref-struct-napi定义结构体PictureStruct
  3. 加载C库:使用ffi-napi加载C库,并声明对应的函数原型。
  4. 调用函数:调用C库函数获取返回的结构体指针。
  5. 解引用指针:使用.deref()方法解引用data指针。
  6. 数据读取:将解引用后的数据转换成Buffer对象,以便于后续处理和打印。

这样,你就可以正确地读取并处理通过C库返回的内存指针中的数据了。


据我所知,你只能在C里面把值取出来给NodeJS

多谢回复! 我实验过返回的picptr对象,通过deref()我可以得到pts 成员的值, 说明是可以返回指针的,只要deref后是nodejs中可识别的数据结构 只是由于deref(picptr)后得到的是一个 pic_t对象因此可以直接 使用pic_t.pts来访问 但若我直接对 var data = picture.data0; data.deref()之后,仅仅是一个uint8_t,不知到如何能转化成类似数组的对象

撸住,你的ref-struct库在哪里下的?

写好 package.json npm install 就可以下到

装好了,3ks

ref、ref-struct、ffi在git的地址是多少?我没搜索到啊

你到npm页面,搜索到addon的介绍,有链接的 比如: https://www.npmjs.org/package/ffi 其他查找方式相同

在这个问题中,你需要通过 ffiref 库处理从 C 库返回的内存指针,并从中读取数据。关键在于正确地解引用指针并访问其中的数据。

首先,你需要确保你已经安装了 ffiref 库。你可以通过以下命令安装它们:

npm install ffi ref

接下来是具体的解决方案:

  1. 定义类型:定义 uint8_t 类型及其指针类型。
  2. 定义结构体:定义你的结构体 pic_t,它包含 data 字段(一个指向 uint8_t 的指针)和其他字段。
  3. 解引用指针:从 C 库回调中获得 picptr 对象后,需要解引用它以访问其内容。
  4. 读取 data 指针:从解引用后的结构体中获取 data 指针,并将其转换为缓冲区以便读取数据。

以下是示例代码:

const ffi = require('ffi-napi');
const ref = require('ref-napi');
const Struct = require('ref-struct-di')(ref);

// 定义类型
const uint8_t = ref.types.uint8;
const int64_t = require('ref-int64')();

// 定义结构体
const pic_t = new Struct({
    data: ref.refType(uint8_t),
    linesize: 'int',
    pts: int64_t,
    dts: int64_t,
    duration: 'int'
});

// 定义 picptr 类型
const picptr = ref.refType(pic_t);

// 假设我们有一个 C 函数返回 picptr
const someCFunction = new ffi.Library('./some-c-lib', {
    someFunction: [picptr, []]
});

// 调用函数
const result = someCFunction.someFunction();

// 解引用结果
const pic = result.deref();

// 获取 data 指针并转换为 Buffer
const dataPointer = pic.data.readPointer();
const dataBuffer = dataPointer.readPointer(0, pic.linesize);

// 打印数据
for (let i = 0; i < 10; i++) { // 只打印前10个字节
    console.log(dataBuffer.readUInt8(i));
}

console.log('canvas render one frame, pts', pic.pts);

解释

  • 定义类型和结构体:定义 uint8_tint64_t 和结构体 pic_t
  • 调用 C 函数:假设 someCFunction 是一个返回 picptr 的 C 函数。
  • 解引用指针:从 picptr 中解引用得到 pic 结构体。
  • 读取 data 指针:通过 data.readPointer() 获取 data 指针,然后使用 readPointer 读取数据。
  • 打印数据:将数据打印出来,这里只打印了前 10 个字节。

这样你就可以正确地读取和使用从 C 库返回的 data 指针中的数据了。

回到顶部