< 返回版块

chaoxi24 发表于 2021-04-06 00:39

下面的函数使用winapi发送按键,它构造了两个了INPUT结构,除了wScan是变化的,其他部分完全是固定的。

我尝试优化它。起初是尝试用一个自定义结构代替INPUT,因为它嵌套了KEYBDINPUT,还必须用"transmute_copy"。尝试失败,用新结构发送按键完全无反应。

我又尝试把 KEYBDINPUT 结构复制到本地来,从Winapi文档复制出来的一模一样的代码,结果怎么试,还是无效。

我又进行了第三种尝试。我打算构造一个static-mut二进制变量,每次使用时修改下wScan位置,然后给SendInput输入内存地址,感觉是最有效率的方案。也失败了,没找到将inputs转换为二进制数据的方法,也不如何如何编辑这些二进制。

请问大家有什么优化方案吗?至少把"transmute_copy"这个步骤去掉。。。。

pub fn send_key(c: u16) {
	let mut inputs: Vec<INPUT> = vec![
                          INPUT { type_: 1,
                                  u: unsafe {
                                          transmute_copy(&KEYBDINPUT { wVk: 0,
                                                                       wScan: c,
                                                                       dwFlags: 4,
                                                                       time: 0,
                                                                       dwExtraInfo: 0 })
                                  }, },
                          INPUT { type_: 1,
                                  u: unsafe {
                                          transmute_copy(&KEYBDINPUT { wVk: 0,
                                                                       wScan: c,
                                                                       dwFlags: 6,
                                                                       time: 0,
                                                                       dwExtraInfo: 0 })
                                  }, }
	];
	unsafe {
		SendInput(inputs.len() as u32, inputs.as_mut_ptr(), size_of::<INPUT>() as i32);
	}
}

评论区

写评论
作者 chaoxi24 2021-04-06 19:49

谢谢。没错,unsafe是union标配。今天是第一次接触到union,原来结构还可以这么用。

Neutron3529 2021-04-06 19:43

没记错union直接就是unsafe……

只要想操作数据,无论读写,都是unsafe

--
👇
dyz1990: 去掉transmute_copy 你可以使用union

https://doc.rust-lang.org/reference/items/unions.html

像这样:

#[repr(C)]
union MyUnion {
    data: [u8;size_of::<KEYBDINPUT>],
    input: KEYBDINPUT,
}
dyz1990 2021-04-06 10:21

去掉transmute_copy 你可以使用union

https://doc.rust-lang.org/reference/items/unions.html

像这样:

#[repr(C)]
union MyUnion {
    data: [u8;size_of::<KEYBDINPUT>],
    input: KEYBDINPUT,
}
johnmave126 2021-04-06 03:44

试试windows-rs

1 共 4 条评论, 1 页