RUST 调用 C++的 lib 请教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hkhk366
V2EX    Rust

RUST 调用 C++的 lib 请教

  •  
  •   hkhk366 2024-10-07 14:24:34 +08:00 204 次点击
    这是一个创建于 370 天前的主题,其中的信息可能已经有所发展或是发生改变。

    新人学习 rust ffi ,实在搞不定,特来请教一下 下面段代码主要是实现一个简单的字符串然后通过 FFI 调用 hyperscan (这是一个 C++写的库,我通过 lib 调用,完全静态编译)的正则表达式同时匹配多个 pattern ,然后打印每一个 pattern 出现的第一个位置即可,如果没出现打印-1 。 但是这个代码我怎么改都是-1 或者 0 ,就是不能有正确结果,我问了多个 AI ,但是都始终无法解决这个问题,所以想向大神请教一下,非常感谢。

    运行结果如下:

    Hyperscan 版本: 5.4.2 2024-10-06 模式 "test" 未出现,位置: -1 模式 "string" 未出现,位置: -1 模式 "example" 未出现,位置: -1 模式 "中文" 未出现,位置: -1 

    完整代码如下:

    use std::ffi::{CStr, CString}; use std::os::raw::{c_int, c_uint, c_void}; use std::ptr; const HS_MODE_BLOCK: c_uint = 1; const HS_FLAG_LITERAL: c_uint = 1 << 10; // 添加 HS_FLAG_LITERAL 常量 #[link(name = "hs")] extern "C" { fn hs_version() -> *const i8; pub fn hs_compile_multi( expressions: *const *const i8, flags: *const c_uint, ids: *const c_uint, elements: c_uint, mode: c_uint, platform: *const c_void, db: *mut *mut hs_database_t, compile_err: *mut *mut hs_compile_error_t, ) -> c_int; pub fn hs_alloc_scratch( db: *const hs_database_t, scratch: *mut *mut hs_scratch_t, ) -> c_int; pub fn hs_free_scratch( scratch: *mut hs_scratch_t, ) -> c_int; pub fn hs_scan( db: *const hs_database_t, data: *const i8, length: c_uint, flags: c_uint, scratch: *mut hs_scratch_t, match_event_handler: Option< extern "C" fn( id: c_uint, from: u64, to: u64, flags: c_uint, context: *mut c_void, ) -> c_int, >, context: *mut c_void, ) -> c_int; pub fn hs_free_database(db: *mut hs_database_t) -> c_int; pub fn hs_free_compile_error(error: *mut hs_compile_error_t); } pub enum hs_database_t {} pub enum hs_scratch_t {} #[repr(C)] pub struct hs_compile_error_t { pub message: *const i8, pub expression: c_int, } const HS_SUCCESS: c_int = 0; extern "C" fn event_handler( id: c_uint, from: u64, _to: u64, _flags: c_uint, context: *mut c_void, ) -> c_int { unsafe { let positiOns= context as *mut u64; let pos_ptr = positions.add(id as usize); if *pos_ptr == u64::MAX { *pos_ptr = from; } } 0 } fn main() { unsafe { // 获取并打印 Hyperscan 版本 let version = hs_version(); let c_str = CStr::from_ptr(version); let str_slice = c_str.to_str().unwrap(); println!("Hyperscan 版本: {}", str_slice); // 定义要匹配的模式列表 let patterns = vec!["test", "string", "example", "中文"]; // 将模式转换为 CString let c_patterns: Vec<CString> = patterns .iter() .map(|s| CString::new(*s).unwrap()) .collect(); // 创建 expressions 、flags 、ids 数组 let expressions: Vec<*const i8> = c_patterns.iter().map(|s| s.as_ptr()).collect(); // 使用 HS_FLAG_LITERAL 标志 let flags: Vec<c_uint> = vec![HS_FLAG_LITERAL; patterns.len()]; let ids: Vec<c_uint> = (0..patterns.len() as c_uint).collect(); // 编译模式 let mut db: *mut hs_database_t = ptr::null_mut(); let mut compile_err: *mut hs_compile_error_t = ptr::null_mut(); let compile_result = hs_compile_multi( expressions.as_ptr(), flags.as_ptr(), ids.as_ptr(), patterns.len() as c_uint, HS_MODE_BLOCK, ptr::null(), &mut db, &mut compile_err, ); if compile_result != HS_SUCCESS { if !compile_err.is_null() { let err = &*compile_err; let message = CStr::from_ptr(err.message).to_string_lossy(); println!("编译错误: {}", message); hs_free_compile_error(compile_err); } else { println!("未知的编译错误"); } return; } // 分配 scratch 空间 let mut scratch: *mut hs_scratch_t = ptr::null_mut(); let alloc_result = hs_alloc_scratch(db, &mut scratch); if alloc_result != HS_SUCCESS { println!("hs_alloc_scratch 失败"); hs_free_database(db); return; } // 定义输入字符串 let input = "This is a test string for example purposes 中文测试."; // 初始化匹配位置数组 let mut match_positions: Vec<u64> = vec![u64::MAX; patterns.len()]; // 执行扫描 let scan_result = hs_scan( db, input.as_ptr() as *const i8, input.len() as c_uint, 0, scratch, Some(event_handler), match_positions.as_mut_ptr() as *mut c_void, ); if scan_result != HS_SUCCESS { println!("hs_scan 失败,错误代码: {}", scan_result); hs_free_scratch(scratch); hs_free_database(db); return; } // 输出结果 for (i, pattern) in patterns.iter().enumerate() { let pos = match_positions[i]; if pos != u64::MAX { println!("模式 \"{}\" 首次出现位置: {}", pattern, pos); } else { println!("模式 \"{}\" 未出现,位置: -1", pattern); } } // 释放资源 hs_free_scratch(scratch); hs_free_database(db); } } 
    5 条回复    2024-10-07 22:33:24 +08:00
    PTLin
        1
    PTLin  
       2024-10-07 15:34:07 +08:00
    调用 cpp 的库用 https://cxx.rs/ ,cpp 的 api 和 c 不一样,用 extern "C"未必好使。
    gwy15
        2
    gwy15  
       2024-10-07 15:56:47 +08:00
    const HS_FLAG_LITERAL: c_uint = 1 << 10; // 添加 HS_FLAG_LITERAL 常量

    这一行的问题,换成其他的可以正常匹配
    gwy15
        3
    gwy15  
       2024-10-07 15:58:06 +08:00
    * Compile flag: Don't do any match reporting.
    *
    * This flag instructs Hyperscan to ignore match reporting for this expression.
    * It is designed to be used on the sub-expressions in logical combinations.
    */
    #define HS_FLAG_QUIET 1024

    你给的 flag 会导致 onEvent 不被调用,自然也就不会写入结果
    hkhk366
        4
    hkhk366  
    OP
       2024-10-07 22:30:05 +08:00
    @gwy15 谢谢回复,但是我把 HS_FLAG_LITERAL 改成了 0 或者其他值后,输出结果是下面,还是不对,头疼
    Hyperscan 版本: 5.4.2 2024-10-06
    模式 "test" 首次出现位置: 0
    模式 "string" 首次出现位置: 0
    模式 "example" 首次出现位置: 0
    模式 "中文" 首次出现位置: 0
    gwy15
        5
    gwy15  
       2024-10-07 22:33:24 +08:00
    @hkhk366 你自己再研究下你的 flag ,应该是你的 event handler 没写对。你在 event handler 里面打印 to 参数是能发现是正确传递了的。这个库我也没用过,你仔细读文档吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     838 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:39 PVG 05:39 LAX 14:39 JFK 17:39
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86