首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Raku NativeCall to Rust FFI CArray尺寸限制- SegFault

Raku NativeCall to Rust FFI CArray尺寸限制- SegFault
EN

Stack Overflow用户
提问于 2022-07-06 10:26:25
回答 1查看 102关注 0票数 6

下面是最小值(?)我的代码的可复制示例。这是压力测试/基准测试的第一关,WIP模块Dan::Polars。

在Rust中,我使用以下代码创建了一个libmre.so

代码语言:javascript
复制
  1 use libc::c_char;
  2 use libc::size_t;
  3 use std::slice;
  4 use std::ffi::*; //{CStr, CString,}
  5 
  6 //  Container
  7 
  8 pub struct VecC {
  9     ve: Vec::<String>,
 10 }   
 11 
 12 impl VecC {
 13     fn new(data: Vec::<String>) -> VecC               
 14     {   
 15         VecC {
 16             ve: data,
 17         }   
 18     }   
 19     
 20     fn show(&self) {
 21         println!{"{:?}", self.ve};
 22     }   
 23 }   
 24     
 25 #[no_mangle]
 26 pub extern "C" fn ve_new_str(ptr: *const *const c_char, len: size_t)                        
 27     -> *mut VecC {    
 28     
 29     let mut ve_data = Vec::<String>::new();
 30     unsafe {
 31         assert!(!ptr.is_null());
 32         
 33         for item in slice::from_raw_parts(ptr, len as usize) {
 34             ve_data.push(CStr::from_ptr(*item).to_string_lossy().into_owned());
 35         };  
 36     };  
 37     
 38     Box::into_raw(Box::new(VecC::new(ve_data)))
 39 }   
 40 
 41 #[no_mangle]
 42 pub extern "C" fn ve_show(ptr: *mut VecC) {
 43     let ve_c = unsafe {
 44         assert!(!ptr.is_null());
 45         &mut *ptr
 46     };  
 47     
 48     ve_c.show();
 49 }  

而这个Cargo.toml

代码语言:javascript
复制
  1 [package]
  2 name = "mre"
  3 version = "0.1.0"
  4 edition = "2021"
  5 
  6 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
  7 
  8 [dependencies]
  9 libc = "0.2.126"
 10 
 11 [lib]
 12 name = "mre"
 13 path = "src/lib.rs"
 14 crate-type = ["cdylib"]

在Raku中,我像这样使用libmre.so

代码语言:javascript
复制
  1 #!/usr/bin/env raku
  2 use lib '../lib';
  3 
  4 use NativeCall;
  5 
  6 #my $output;    #mre tried to move decl to here to avoid going out of scope
  7 sub carray( $dtype, @items ) {
  8     my $output := CArray[$dtype].new();
  9     loop ( my $i = 0; $i < @items; $i++ ) {
 10         $output[$i] = @items[$i]
 11     }
 12     say $output;
 13     $output
 14 }   
 15     
 16 ### Container Classes that interface to Rust lib.rs ###
 17 
 18 constant $n-path    = '../mre/target/debug/mre';
 19 
 20 class VecC is repr('CPointer') is export {
 21     sub ve_new_str(CArray[Str],size_t) returns VecC is native($n-path) { * }
 22     sub ve_show(VecC) is native($n-path) { * }
 23     
 24     method new(@data) { 
 25         ve_new_str(carray(Str, @data), @data.elems );
 26     }   
 27     
 28     method show {
 29         ve_show(self)
 30     }   
 31 }   
 32 
 33 my \N = 100;   #should be 2e9  #fails between 30 and 100
 34 my \K = 100;   
 35 
 36 sub randChar(\f, \numGrp, \N) {
 37     my @things = [sprintf(f, $_) for 1..numGrp];
 38     @things[[1..numGrp].roll(N)];
 39 }   
 40 
 41 my @data = [randChar("id%03d", K, N)];
 42 
 43 my $vec = VecC.new( @data );
 44 $vec.show;

当\N <30时,输出运行良好,如下所示:

代码语言:javascript
复制
NativeCall::Types::CArray[Str].new
["id098", "id035", "id024", "id067", "id051", "id025", "id024", "id092", "id044", "id042", "id033", "id004", "id100", "id091", "id087", "id059", "id031", "id063", "id019", "id035"]

但是,当n> 50时,我得到:

代码语言:javascript
复制
NativeCall::Types::CArray[Str].new
Segmentation fault (core dumped)

这是:

代码语言:javascript
复制
Welcome to Rakudo™ v2022.04.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.04.
on ubuntu

因为基准测试要求\N为2e9,所以我需要一些帮助来尝试和解决这个问题。

欢迎您在码头集线器上使用p6steve/raku-dan:polars-2022.02-arm64 (或-amd64),如果您想在家里尝试这一点的话。别忘了第一次去cargo build。这包括RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-06 11:32:51

randChar函数中有一个错误

代码语言:javascript
复制
sub randChar(\f, \numGrp, \N) {
    my @things = [sprintf(f, $_) for 1..numGrp];     
    @things[[1..numGrp].roll(N)];
}   

您正在用从1numGrp的索引来索引1数组,但是@things的最大索引是numGrp - 1。因此,有时返回数组的一个(或多个)元素中有一个(Any)而不是一个字符串。

你想要的是:

代码语言:javascript
复制
sub randChar(\f, \numGrp, \N) {
    my @things = [sprintf(f, $_) for 1..numGrp];     
    @things.roll(N); # call roll directly on @things
}   
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72881881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档