【问题标题】:Calling Rust from NodeJS从 NodeJS 调用 Rust
【发布时间】:2015-08-20 13:46:35
【问题描述】:

我正在尝试为我的 soup.io 博客构建一个简单的 rust rss 'harvester',然后使用 node.js 将这些条目发布到侨民(因为有一个 npm 包)

我想学习如何从节点使用 rust,所以这就是我构建这个项目的原因。

我的问题是我不知道如何使用正确的类型调用 ffi 函数。

var lib = ffi.Library('target/debug/libmain', {
    'get_soup': ['Vec<Post>', ['String']]
});

'Vec&lt;Post&gt;' 不起作用。 我知道我必须为此使用ref。 但我真的不知道这实际上是如何以及做什么的。

我知道我必须将 rust 类型转换为 javascript?

如何在我的 ffi 函数中使用Vec&lt;Post&gt;?

我的 github 项目:Realtin/suppe

这里是相关代码:

锈代码:

extern crate rss;
extern crate hyper;

use rss::Rss;
use std::io::prelude::*;

#[derive(Debug)]
pub struct Post  {
    title: String,
    link: String,
    description: String,
}

fn main() {
    let user = "realtin".to_string();
    let vec = get_soup(&user);
    println!("{:?}", vec[vec.len()-1]);
}

#[no_mangle]
pub extern fn get_soup(user: &str) ->Vec<Post>{
    let url = format!("http://{}.soup.io/rss", user);
    let mut vec = Vec::new();

    let client = hyper::Client::new();
    let mut response = client.get(&url).send().unwrap();

    let mut suppe = String::new();
    let _= response.read_to_string(&mut suppe);

    let rss::Rss(channel) = suppe.parse::<rss::Rss>().unwrap();

    for item in channel.items.into_iter().rev() {
      let item_object = Post {
           title: item.title.unwrap(),
           link: item.link.unwrap(),
           description: item.description.unwrap(),
        };
        vec.push(item_object);
    }
    return vec;
}

NodeJS 代码:

var ref = require('ref');
var StructType = require("ref-struct");
var ffi = require('ffi');

var Post = StructType({
  title: String,
  link: String,
  description: String,
});
// var vecPost = ref.refType(ref.types.Object);

var lib = ffi.Library('target/debug/libmain', {
    'get_soup': ['Vec<Post>', ['String']]
});

var posts = lib.get_soup("realtin");

【问题讨论】:

  • 您可能也对The Rust FFI Omnibus 感兴趣。
  • @Shepmaster 哦,这太棒了!我正在寻找这样的东西!
  • 太棒了!如果您正在寻找任何具体示例或任何可以更清楚的内容,请务必在 Github 上提交任何问题。

标签: node.js rust node-ffi


【解决方案1】:

简短的回答:你不能为 FFI 绑定导出任何 Rust 函数,你需要专门导出与 C 兼容的 Rust 函数。

具体来说,这意味着您只需要公开 C-struct 兼容对象或公开不透明指针(只能通过 Rust 函数操作)。

在您的情况下,Vec&lt;Post&gt; 与 FFI 中的用法不兼容,因为 Vec 不兼容。

您可以在FFI Guide找到更多信息。

【讨论】:

  • 谢谢!这是有道理的:)
【解决方案2】:

有些数据类型可以直接传递,使用你的方法

使用 FFI 导出 Rust https://svartalf.info/posts/2019-03-01-exposing-ffi-from-the-rust-library/

然后使用类似https://github.com/node-ffi/node-ffi的东西从nodejs调用它

可能没有使用您需要的结构,但您可以在一端或两端转换数据。 作为最后的手段,您可以使用 JSON。会有一些开销,但不会很多

https://stackoverflow.com/a/42498913/3232611

可以使用协议缓冲区,如果 JSON 性能是瓶颈,但在大多数情况下它不值得复杂

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2018-02-18
    • 2019-05-19
    • 2014-01-24
    • 2015-04-15
    相关资源
    最近更新 更多