首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rust生成的节点FFI调用和动态库

Rust生成的节点FFI调用和动态库
EN

Stack Overflow用户
提问于 2019-09-16 18:24:59
回答 2查看 258关注 0票数 0

我正在尝试将node-ffi与从rust生成的动态库一起使用。这是铁锈链接,https://github.com/petrachor/pairing-ariel。如何让JavaScript正确调用rust函数并返回预期结果?要编译rust,首先将crate-type(Cargo.toml)更改为"dylib",然后使用cargo build --release

代码语言:javascript
复制
#[repr(C)]
#[derive(Debug)]
pub struct ArrayStruct<T> {
    d: *mut T,
    len: usize,
}

#[no_mangle]
pub extern "C" fn g2_get_one(g: ArrayStruct<u8>) -> bool {
    return panic::catch_unwind(|| {
        g2_to_raw(G2Affine::get_generator(), g);
    }).is_ok();
}

我的节点代码通过FFI调用rust

代码语言:javascript
复制
var ref = require('ref');
var FFI = require('ffi');
var Struct = require('ref-struct');

//var IArrayType = require('ref-array');

var ArrayStruct8 = Struct({
    'd': "uchar*",
    'len': "int32"
});

var lib = new FFI.Library('target/release/libpairing', { 'g2_get_zero': [ ref.types.bool, [ ArrayStruct8] ]});

var buf = new Buffer.alloc(192);
var a8 = new ArrayStruct8({d: buf, len: 192});

lib.g2_get_zero(a8);
console.dir(a8);

我希望8.b包含无符号字符* .当我做console.log(a8.d)的时候,我得到了"@“。外面有些东西我还没修好,请帮帮我。

EN

回答 2

Stack Overflow用户

发布于 2019-09-16 22:55:18

一旦我在家准备好全套工具,让实际的struct-based示例正常工作,就会对这个示例进行编辑。

通过问题中给出的实施跨越FFI边界的症状如下:

保持FFI boundary)

  • Buffer完整性(在FFI

  • 完整性两侧的相同指针表面保持而不是保持或更新)。从Rust到NodeJS,缓冲区应该已经更新,但不是

在处理像这样的低字段数修改结构时,快速的解决方案是传递一个fat指针(指针+长度),例如:

代码语言:javascript
复制
#[no_mangle]
pub extern "C" fn do_something_with_array(buf: *mut u8, len: u32) -> u32 {
    unsafe {
        buf.write_bytes(1, 3);
    }
    3
}

在nodeJS前面有相应的FFI定义:

代码语言:javascript
复制
var lib = new FFI.Library('target/debug/libtest2', {
  'do_something_with_array': [ 'int', ['pointer', 'int'] ]
});

var buf = new Buffer.alloc(192);
var new_len = lib.do_something_with_array(buf, 192);
var new_buf = buf.slice(0, new_len);

似乎ref-struct需要某种类型的同步,因为底层内存具有正确的内容。

票数 0
EN

Stack Overflow用户

发布于 2019-09-18 05:26:55

在试图弄清楚如何保持或更新缓冲区完整性时,我注意到我并不真正需要ref-struct或其他复杂的东西。我想我是在利用C语言内部的结构布局。只需要指针和它的长度。例如,

代码语言:javascript
复制
#[repr(C)]
#[derive(Debug)]
pub struct ArrayStruct<T> {
    d: *mut T,
    len: usize,
}

#[no_mangle]
pub extern "C" fn g2_get_one(g: ArrayStruct<u8>) -> bool {
    return panic::catch_unwind(|| {
        g2_to_raw(G2Affine::get_generator(), g);
    }).is_ok();
}

要从Nodejs调用g2_get_one,请执行以下操作:

代码语言:javascript
复制
var lib = new FFI.Library('target/debug/libtest2', {
  'do_something_with_array': [ 'int', ['pointer', 'int'] ]
});

var buf = new Buffer.alloc(192);
var new_len = lib.do_something_with_array(buf, 192);

只要遵循这个简单的规则,你就可以在Rust中有多个结构作为参数,并且这个规则也会得到遵守。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57954884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档