如何使用Rust和winapi板条箱为Windows中的事件创建订阅?
我正在尝试使用从订阅Windows事件,但得到了如何使用Rust和winapi板条箱为Windows中的事件创建订阅?,winapi,rust,Winapi,Rust,我正在尝试使用从订阅Windows事件,但得到了错误\u无效\u参数 我找不到铁锈的例子,但确实找到了一个 生成错误\u无效\u参数的我的代码: fn main() { unsafe { let mut callback: winapi::um::winevt::EVT_SUBSCRIBE_CALLBACK = None; let mut session = std::ptr::null_mut(); let mut signal_even
错误\u无效\u参数
我找不到铁锈的例子,但确实找到了一个
生成错误\u无效\u参数的我的代码
:
fn main() {
unsafe {
let mut callback: winapi::um::winevt::EVT_SUBSCRIBE_CALLBACK = None;
let mut session = std::ptr::null_mut();
let mut signal_event = std::ptr::null_mut();
let mut bookmark = std::ptr::null_mut();
let mut context = std::ptr::null_mut();
let channel_path = "Security";
let channel_path: winnt::LPWSTR = to_wchar(channel_path);
let query = "Event/System[EventID=4624]";
let query: winnt::LPWSTR = to_wchar(query);
let event_handle = winevt::EvtSubscribe(
session,
signal_event,
channel_path,
query,
bookmark,
context,
callback,
winevt::EvtSubscribeStartAtOldestRecord,
);
//println!("{:?}", &event_handle);
println!("{:?}", &winapi::um::errhandlingapi::GetLastError());
} //unsafe end
}
fn to_vec(str: &str) -> Vec<u16> {
return OsStr::new(str)
.encode_wide()
.chain(Some(0).into_iter())
.collect();
}
fn to_wchar(str: &str) -> *mut u16 {
return to_vec(str).as_mut_ptr();
}
fn main(){
不安全{
让mut回调:winapi::um::winevt::EVT\u SUBSCRIBE\u callback=None;
让mut session=std::ptr::null_mut();
让mut signal_event=std::ptr::null_mut();
让mut bookmark=std::ptr::null_mut();
让mut context=std::ptr::null_mut();
让通道_path=“安全”;
让通道路径:winnt::LPWSTR=to_wchar(通道路径);
让query=“事件/系统[EventID=4624]”;
let query:winnt::LPWSTR=to_wchar(查询);
让事件句柄=winevt::EvtSubscribe(
一场
信号灯事件,
英吉利海峡,
查询
书签,
上下文
回拨,
winevt::EVT订阅StartOldEstrecord,
);
//println!(“{:?}”和事件句柄);
println!(“{:?},&winapi::um::errhandlingapi::GetLastError());
}//不安全端
}
fn到_vec(str:&str)->vec{
返回OsStr::新建(str)
.encode_wide()
.chain(一些(0).into_iter())
.收集();
}
fn至_wchar(str:&str)->*mut u16{
返回到_vec(str).as_mut_ptr();
}
各州的文件:
SignalEvent
[…]如果回调
参数不可用,则此参数必须为NULL
NULL
回调
[…]如果SignalEvent
参数为空,则此参数必须为NULL
非NULL
此处未说明的含义是必须提供这些参数中的一个。显式地不允许同时传递这两个事件,但同时传递这两个事件都没有意义,否则代码将无法接收事件
传递其中一个值将导致代码开始工作
编辑上,这是一个很好的例子,说明Rust枚举是一种更好的API建模方法。这将清楚地表明这两种选择是相互排斥的,需要一种:
enum Subscriber {
EventObject(HANDLE),
Callback(EVT_SUBSCRIBE_CALLBACK),
}
顺便说一句,您对_wchar的
实现不正确,可能会导致内存不安全to_vec
分配内存,您获取一个指向它的指针,然后释放该内存,创建一个悬空指针。坏指针由unsafe
块内的C代码读取-需要部分原因unsafe
您要么需要使用mem::forget
,如中所示(然后需要以某种方式防止内存泄漏),要么需要引用数据而不是原始指针。状态文档:
SignalEvent
[…]如果回调
参数不可用,则此参数必须为NULL
NULL
回调
[…]如果SignalEvent
参数为空,则此参数必须为NULL
非NULL
此处未说明的含义是必须提供这些参数中的一个。显式地不允许同时传递这两个事件,但同时传递这两个事件都没有意义,否则代码将无法接收事件
传递其中一个值将导致代码开始工作
编辑上,这是一个很好的例子,说明Rust枚举是一种更好的API建模方法。这将清楚地表明这两种选择是相互排斥的,需要一种:
enum Subscriber {
EventObject(HANDLE),
Callback(EVT_SUBSCRIBE_CALLBACK),
}
顺便说一句,您对_wchar
的实现不正确,可能会导致内存不安全to_vec
分配内存,您获取一个指向它的指针,然后释放该内存,创建一个悬空指针。坏指针由unsafe
块内的C代码读取-需要部分原因unsafe
您要么需要使用mem::forget
,如中所示(然后您需要以某种方式防止内存泄漏),要么需要引用数据,而不是原始指针。您的和位于println代码>是不需要的(),并且助手中显式的返回
是非惯用的,并且.chain(一些(0))
就足够了。您的和在println中代码>是不需要的(),并且助手中显式的返回
s是非惯用的,并且.chain(一些(0))
就足够了。