从 NodeJS 调用 Rust
Calling Rust from NodeJS
我试图为我的 soup.io 博客构建一个简单的 rust rss 'harvester' 然后 post 使用 node.js 将这些条目 node.js (因为有一个 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");
简短的回答:您不能为 FFI 绑定导出任何 Rust 函数,您需要专门导出与 C 兼容的 Rust 函数。
具体来说,这意味着您只需要公开 C 结构兼容对象或公开不透明指针(只能通过 Rust 函数进行操作)。
在您的情况下,Vec<Post>
与 FFI 中的用法不兼容,因为 Vec
不兼容。
您可以在 FFI Guide 中找到更多信息。
使用您的方法可以直接传递某些数据类型
使用 FFI 导出 Rust
https://svartalf.info/posts/2019-03-01-exposing-ffi-from-the-rust-library/
然后使用 https://github.com/node-ffi/node-ffi
从 nodejs 调用它
可能没有使用您需要的结构,但您可以在一端或两端转换数据。
作为最后的手段,您可以使用 JSON。会有一些开销,但不会很多
可以使用协议缓冲区,如果JSON性能是瓶颈,但在大多数情况下不值得复杂
我试图为我的 soup.io 博客构建一个简单的 rust rss 'harvester' 然后 post 使用 node.js 将这些条目 node.js (因为有一个 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");
简短的回答:您不能为 FFI 绑定导出任何 Rust 函数,您需要专门导出与 C 兼容的 Rust 函数。
具体来说,这意味着您只需要公开 C 结构兼容对象或公开不透明指针(只能通过 Rust 函数进行操作)。
在您的情况下,Vec<Post>
与 FFI 中的用法不兼容,因为 Vec
不兼容。
您可以在 FFI Guide 中找到更多信息。
使用您的方法可以直接传递某些数据类型
使用 FFI 导出 Rust https://svartalf.info/posts/2019-03-01-exposing-ffi-from-the-rust-library/
然后使用 https://github.com/node-ffi/node-ffi
从 nodejs 调用它可能没有使用您需要的结构,但您可以在一端或两端转换数据。 作为最后的手段,您可以使用 JSON。会有一些开销,但不会很多
可以使用协议缓冲区,如果JSON性能是瓶颈,但在大多数情况下不值得复杂