- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图使用Rust中的winapi crate 将数据设置到Windows cipboard中(Rust和win32 api都是新的)。
SetClipboardData调用的输入需要文件类型,C通用指针或Rust中的*mut libc::c_void
。
(以下链接的文档)
在最终版本中,我计划复制图像文件,但是使用文本字符串进行测试失败,这是它的代码:
extern crate winapi;
extern crate libc;
fn main() {
let mut test = "test\r\n";
let test_ptr: *mut libc::c_void = &mut test as *mut _ as *mut libc::c_void;
loop {
if (condition)
{
// let mut test = "test\r\n"; // these commented lets are refered to issue 2
// let test_ptr: *mut libc::c_void = &mut test as *mut _ as *mut libc::c_void;
unsafe {winapi::um::winuser::SetClipboardData(winapi::um::winuser::CF_TEXT, test_ptr);}
}
}
}
process didn't exit successfully: exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)
。
最佳答案
所提供的代码存在多个问题。最突出的是,SetClipboardData希望将HANDLE
分配给使用GlocalAlloc分配的内存。严格要求在执行操作之前调用OpenClipboard。
一个更微妙的问题是与CF_TEXT一起使用的字符编码要求。此剪贴板格式需要使用ANSI(代码页)编码的文本。由于Rust整个内部都使用Unicode,因此最好改用CF_UNICODETEXT
并将其转换为UTF-16。
以下是一个粗略的实现:
[dependencies]
winapi = { version = "0.3.8", features = ["winuser", "winbase"] }
use std::ptr;
use winapi::um::winbase::{GlobalAlloc, GlobalFree, GlobalLock, GlobalUnlock, GMEM_MOVEABLE};
use winapi::um::winuser::{CloseClipboard, OpenClipboard, SetClipboardData, CF_UNICODETEXT};
fn copy_to_clipboard(text: &str) {
// Needs to be UTF-16 encoded
let mut text_utf16: Vec<u16> = text.encode_utf16().collect();
// And zero-terminated before passing it into `SetClipboardData`
text_utf16.push(0);
// Allocate memory
let hglob =
unsafe { GlobalAlloc(GMEM_MOVEABLE, text_utf16.len() * std::mem::size_of::<u16>()) };
// Retrieve writeable pointer to memory
let dst = unsafe { GlobalLock(hglob) };
// Copy data
unsafe { ptr::copy_nonoverlapping(text_utf16.as_ptr(), dst as _, text_utf16.len()) };
// Release writeable pointer
unsafe { GlobalUnlock(hglob) };
// Everything is set up now, let's open the clipboard
unsafe { OpenClipboard(ptr::null_mut()) };
// And apply data
unsafe { SetClipboardData(CF_UNICODETEXT, hglob) };
// Clean up
unsafe { GlobalFree(hglob) };
unsafe { CloseClipboard() };
}
fn main() {
copy_to_clipboard("Hello, world!");
}
[dependencies]
winapi = { version = "0.3.8", features = ["winuser", "winbase"] }
scopeguard = "1.1.0"
use scopeguard::defer;
use std::io::Error;
use std::ptr;
use winapi::shared::minwindef::FALSE;
use winapi::um::winbase::{GlobalAlloc, GlobalFree, GlobalLock, GlobalUnlock, GMEM_MOVEABLE};
use winapi::um::winuser::{CloseClipboard, OpenClipboard, SetClipboardData, CF_UNICODETEXT};
fn copy_to_clipboard(text: &str) -> Result<(), Error> {
// Needs to be UTF-16 encoded
let mut text_utf16: Vec<u16> = text.encode_utf16().collect();
// And zero-terminated before passing it into `SetClipboardData`
text_utf16.push(0);
// Allocate memory
let hglob =
unsafe { GlobalAlloc(GMEM_MOVEABLE, text_utf16.len() * std::mem::size_of::<u16>()) };
if hglob == ptr::null_mut() {
return Err(Error::last_os_error());
}
// Ensure cleanup on scope exit
defer!(unsafe { GlobalFree(hglob) };);
// Retrieve writeable pointer to memory
let dst = unsafe { GlobalLock(hglob) };
if dst == ptr::null_mut() {
return Err(Error::last_os_error());
}
// Copy data
unsafe { ptr::copy_nonoverlapping(text_utf16.as_ptr(), dst as _, text_utf16.len()) };
// Release writeable pointer
unsafe { GlobalUnlock(hglob) };
// Everything is set up now, let's open the clipboard
let success = unsafe { OpenClipboard(ptr::null_mut()) } != FALSE;
if !success {
return Err(Error::last_os_error());
}
// Ensure cleanup on scope exit
defer!(unsafe { CloseClipboard() };);
// And apply data
let success = unsafe { SetClipboardData(CF_UNICODETEXT, hglob) } != ptr::null_mut();
if !success {
return Err(Error::last_os_error());
}
Ok(())
}
fn main() {
copy_to_clipboard("Hello, world!").expect("Failed to copy text to clipboard.");
}
关于winapi - 使用Rust语言使用winapi SetClipboardData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61981453/
我试图使用Rust中的winapi crate 将数据设置到Windows cipboard中(Rust和win32 api都是新的)。 SetClipboardData调用的输入需要文件类型,C通用
我不确定从下面的代码中得到这样的错误(堆损坏)的根本原因是什么。当我单步执行程序时,TCHAR 值被正确分配并复制到剪贴板数据。但是,当它继续执行 SetClipboardData(...) 时崩溃。
我的理解是,一般来说,当您向剪贴板添加句柄时,剪贴板就拥有该句柄,您不负责删除它,也不应该删除它。这就是这里所说的:https://msdn.microsoft.com/en-us/library/w
我有这个组件,我想在 DLL 中使用它来实现系统范围的 Hook : unit ClipboardHook; interface uses Windows, SysUtils, Classes,
我正在开发一些软件,将一个大字符串复制到 Windows 剪贴板以粘贴到其他软件中。在其他软件中粘贴不成功,当我粘贴到记事本中时,初始字符串中的换行符消失了,这就是为什么在其他软件中粘贴失败的原因。我
我是一名优秀的程序员,十分优秀!