用NodeJS调用Rust

10
我想构建一个简单的 Rust Rss “收割机”来发布我的 soup.io 博客,并使用 node.js 将这些条目发布到 diaspora(因为有一个 npm 包)。
我想学习如何从 node 中使用 rust,所以这就是我正在构建这个项目的原因。
我的问题是我不知道如何使用正确的类型调用 ffi 函数。
var lib = ffi.Library('target/debug/libmain', {
    'get_soup': ['Vec<Post>', ['String']]
});
'Vec<Post>'无法使用。 我知道我需要使用ref,但我不真正知道它的用法和作用。
我理解我需要将Rust类型转换为JavaScript?
如何在我的ffi函数中使用Vec<Post>
我的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");

2
你可能也会对The Rust FFI Omnibus感兴趣。 - Shepmaster
@Shepmaster 哦,这太棒了!我一直在寻找这样的东西! - anderspree
太好了!如果您正在寻找特定的示例或需要更清晰的解释,请务必在Github上提交任何问题。 - Shepmaster
2个回答

10
简短回答:你无法导出任何 Rust 函数用于 FFI 绑定,你需要专门导出与 C 兼容的 Rust 函数。
具体来说,这意味着你需要仅暴露 C-struct 兼容对象或暴露不透明指针(只能通过 Rust 函数进行操作)。
在你的情况下,Vec<Post> 不兼容 FFI 中的使用,因为 Vec 不兼容。
你可以在FFI Guide中找到更多信息。

1
谢谢!那很有道理 :) - anderspree

-1

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

使用 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://dev59.com/q5_ha4cB1Zd3GeqP0owU#42498913

如果 JSON 的性能成为瓶颈,可以使用协议缓冲区,但在大多数情况下,这并不值得复杂化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接