从NodeJS调用Rust

and*_*ree 5 node.js rust node-ffi

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

我想学习如何使用节点生锈,这就是我正在构建这个项目的原因.

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

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

'Vec<Post>'不起作用.我知道我必须使用ref它.但我真的不知道实际上是怎么做的.

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

我如何Vec<Post>在我的ffi功能中使用?

我的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;
}
Run Code Online (Sandbox Code Playgroud)

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");
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 7

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

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

在您的情况下,Vec<Post>与FFI中的使用不兼容,因为Vec不是.

您可以在FFI指南中找到更多信息.