Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何从NodeJS中的Rust FFI函数返回字符串值?_Json_Node.js_Rust_Node Ffi - Fatal编程技术网

Json 如何从NodeJS中的Rust FFI函数返回字符串值?

Json 如何从NodeJS中的Rust FFI函数返回字符串值?,json,node.js,rust,node-ffi,Json,Node.js,Rust,Node Ffi,我想生成6个随机数,将它们推到一个向量上,然后使用rustc_serialize将该向量编码为一个JSON字符串,供NodeJ使用 extern板条箱兰德; 外部板条箱锈迹丛生; 使用rand::{OsRng,Rng}; 使用rustc_serialize::json::{self,json,ToJson}; #[没有损坏] pub extern“C”fn generate()->字符串{ 让我们选择:[u8;6]=[1,2,3,4,5,6]; 让mut rand_vec:vec=vec::ne

我想生成6个随机数,将它们推到一个向量上,然后使用
rustc_serialize
将该向量编码为一个JSON字符串,供NodeJ使用

extern板条箱兰德;
外部板条箱锈迹丛生;
使用rand::{OsRng,Rng};
使用rustc_serialize::json::{self,json,ToJson};
#[没有损坏]
pub extern“C”fn generate()->字符串{
让我们选择:[u8;6]=[1,2,3,4,5,6];
让mut rand_vec:vec=vec::new();
让mut rng=匹配OsRng::new(){
Ok(t)=>t,
Err(e)=>panic!(“未能创建OsRng!,{},e),
};
对于0..5中的uu{
随机向量推送(*rng.choose(&chooses.unwrap());
}
json::encode(&rand_vec).unwrap()
}
此代码编译为库
generate_6_rand.dll
。我有一个单独的二进制文件,用来测试这段代码

如果我跑

println!(“{:?},&json::encode(&rand_vec).unwrap());
输出:

“[5,4,3,4,1,3]”//如预期
然后在NodeJS程序中使用我的
.dll

var ffi = require('ffi');
var path = require('path');

var lib = ffi.Library(path.join(__dirname,
  './ffi/generate_6_rand.dll'), {
    generate: [ 'string', [ ]]
  });

console.log(lib.generate());
测验
console.log(lib.generate())

输出:

��.�
它是一个EcmaScript
ArrayBuffer
console.log(新的ArrayBuffer(lib.generate())

输出:

ArrayBuffer{bytellength:0}
它的原链性质是什么?
console.log(lib.generate()。\uuuuu proto\uuuuuu)

输出:

[字符串:“”]
将代码更改为:

var ref = require('ref');
var ArrayType = require('ref-array');
var Int32Array = ArrayType(ref.types.int32);


var lib = ffi.Library(path.join(__dirname,
  '../dice_lib/target/release/generate_6_rand.dll'), {
    generate: [ Int32Array, [ ]]
  });

console.log(new ArrayBuffer(lib.generate()));
输出:

ArrayBuffer{bytellength:0}

为什么FFI函数没有像我期望的那样返回JSON字符串?

感谢Wesley Wiser为我提供了有关
CString
的重要线索。我在中找到了答案

无论是返回JSON字符串还是返回
CString
,预期JSON字符串的内存都在NodeJS程序访问之前被释放

这是我基于那篇文章的解决方案。对于其他新手程序员,请记住我的解决方案可能是理想的,也可能不是理想的:

生锈
extern板条箱兰德;
外部板条箱锈迹丛生;
外部板条箱libc;
使用libc::c_char;
使用rand::{OsRng,Rng};
使用std::ffi::CString;
使用rustc_serialize::json;
#[没有损坏]
发布外部“C”fn generate()->*mut C_char{
让我们选择:[u8;6]=[1,2,3,4,5,6];
让mut rand_vec:vec=vec::new();
让mut rng=匹配OsRng::new(){
Ok(t)=>t,
Err(e)=>panic!(“未能创建OsRng!,{},e),
};
对于0..6中的uu{
随机向量推送(*rng.choose(&chooses.unwrap());
}
让json_string=CString::new(json::encode(&rand_vec).unwrap()).unwrap();
json_string.into_raw()
}
#[没有损坏]
发布外部“C”fn可用内存(指针:*mut C_char){
不安全{
如果指针.is_null(){
返回;
}
CString::from_raw(指针)
};
}
NodeJS
我设置了两个
控制台。log
s显示解除分配前后的输出。

String
s在Rust中不是用来跨越FFI边界的。您可能想要的是让
generate
函数返回
CString
var ffi = require('ffi');
var path = require('path');

var lib = ffi.Library(path.join(__dirname,
  './ffi/generate_6_rand.dll'), {
    generate: [ 'char *' , [ ]],
    free_memory: ['void', ['char *']]
  });

var json_string = lib.generate();

var save_json = JSON.parse(json_string.readCString());

console.log( json_string.readCString()); // Output: [6,1,6,4,1,4]
lib.free_memory(json_string);
console.log(json_string.readCString()); // Output: ��x�