[英]Polymorphism in Rust and trait references (trait objects?)
I'm writing a process memory scanner with a console prompt interface in Rust. 我正在用Rust的控制台提示符界面编写过程内存扫描器。
I need scanner types such as a winapi scanner or a ring0 driver scanner so I'm trying to implement polymorphism. 我需要诸如winapi扫描仪或ring0驱动程序扫描仪之类的扫描仪,因此我正在尝试实现多态。
I have the following construction at this moment: 目前,我的结构如下:
pub trait Scanner {
fn attach(&mut self, pid: u32) -> bool;
fn detach(&mut self);
}
pub struct WinapiScanner {
pid: u32,
hprocess: HANDLE,
addresses: Vec<usize>
}
impl WinapiScanner {
pub fn new() -> WinapiScanner {
WinapiScanner {
pid: 0,
hprocess: 0 as HANDLE,
addresses: Vec::<usize>::new()
}
}
}
impl Scanner for WinapiScanner {
fn attach(&mut self, pid: u32) -> bool {
let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid) };
if handle == 0 as HANDLE {
self.pid = pid;
self.hprocess = handle;
true
} else {
false
}
}
fn detach(&mut self) {
unsafe { CloseHandle(self.hprocess) };
self.pid = 0;
self.hprocess = 0 as HANDLE;
self.addresses.clear();
}
}
In future, I'll have some more scanner types besides WinapiScanner
, so, if I understand correctly, I should use a trait reference ( &Scanner
) to implement polymorphism. 将来,除了WinapiScanner
之外,我WinapiScanner
拥有更多其他扫描仪类型,因此,如果我理解正确,我应该使用特征引用( &Scanner
)实现多态。 I'm trying to create Scanner
object like this (note the comments): 我正在尝试创建这样的Scanner
对象(注意注释):
enum ScannerType {
Winapi
}
pub fn start() {
let mut scanner: Option<&mut Scanner> = None;
let mut scanner_type = ScannerType::Winapi;
loop {
let line = prompt();
let tokens: Vec<&str> = line.split_whitespace().collect();
match tokens[0] {
// commands
"scanner" => {
if tokens.len() != 2 {
println!("\"scanner\" command takes 1 argument")
} else {
match tokens[1] {
"list" => {
println!("Available scanners: winapi");
},
"winapi" => {
scanner_type = ScannerType::Winapi;
println!("Scanner type set to: winapi");
},
x => {
println!("Unknown scanner type: {}", x);
}
}
}
},
"attach" => {
if tokens.len() > 1 {
match tokens[1].parse::<u32>() {
Ok(pid) => {
scanner = match scanner_type {
// ----------------------
// Problem goes here.
// Object, created by WinapiScanner::new() constructor
// doesn't live long enough to borrow it here
ScannerType::Winapi => Some(&mut WinapiScanner::new())
// ----------------------
}
}
Err(_) => {
println!("Wrong pid");
}
}
}
},
x => println!("Unknown command: {}", x)
}
}
}
fn prompt() -> String {
use std::io::Write;
use std::io::BufRead;
let stdout = io::stdout();
let mut lock = stdout.lock();
let _ = lock.write(">> ".as_bytes());
let _ = lock.flush();
let stdin = io::stdin();
let mut lock = stdin.lock();
let mut buf = String::new();
let _ = lock.read_line(&mut buf);
String::from(buf.trim())
}
It's not a full program; 这不是一个完整的程序; I've pasted important parts only. 我只粘贴了重要部分。
What am I doing wrong and how do I implement what I want in Rust? 我在做什么错,如何在Rust中实现我想要的?
Trait objects must be used behind a pointer. 特性对象必须在指针后面使用。 But references are not the only kind of pointers; 但是引用并不是唯一的指针。 Box
is also a pointer! Box
也是指针!
let mut scanner: Option<Box<Scanner>> = None;
scanner = match scanner_type {
ScannerType::Winapi => Some(Box::new(WinapiScanner::new()))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.