C++ vs Rust 实现 Windows 桌面时钟性能与开发效率对比
学习笔记作者:admin日期:2025-05-24点击:35
摘要:对比 C++ 和 Rust 实现 Windows 桌面时钟的性能、开发效率、安全性等方面,提供基于 Rust 的完整代码示例。
桌面时钟实现与技术对比
项目背景
本项目旨在使用 C++ 和 Rust 分别实现一个 Windows 桌面时钟程序,要求窗口始终置顶、每 2 秒更新时间。
C++ vs Rust 对比
维度 | C++ (Win32) | Rust (Win32) | Rust (egui/winit) |
---|---|---|---|
性能 | 极高 | 极高 | 高 |
安全性 | 低(手动管理) | 高(借用检查) | 高 |
开发效率 | 低 | 中等 | 高 |
可维护性 | 差 | 好 | 很好 |
跨平台 | 否 | 否(封装) | 是 |
易学程度 | 高 | 中等 | 中等 |
Rust 实现代码示例
extern crate winapi;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::ptr::null_mut;
use std::time::{SystemTime, UNIX_EPOCH};
use winapi::shared::minwindef::*;
use winapi::shared::ntdef::*;
use winapi::um::libloaderapi::*;
use winapi::um::winuser::*;
const IDT_TIMER: usize = 1;
fn main() {
unsafe {
let h_instance = GetModuleHandleW(null_mut());
let class_name: Vec = OsStr::new("ClockWindowClass")
.encode_wide()
.chain(Some(0).into_iter())
.collect();
let wnd_class = WNDCLASSW {
style: 0,
lpfnWndProc: Some(wnd_proc),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: h_instance,
hIcon: LoadIconW(null_mut(), IDI_APPLICATION),
hCursor: LoadCursorW(null_mut(), IDC_ARROW),
hbrBackground: (COLOR_WINDOW + 1) as HBRUSH,
lpszMenuName: null_mut(),
lpszClassName: class_name.as_ptr(),
};
RegisterClassW(&wnd_class);
let hwnd = CreateWindowExW(
WS_EX_TOPMOST,
class_name.as_ptr(),
to_wstring("桌面时钟").as_ptr(),
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
100,
null_mut(),
null_mut(),
h_instance,
null_mut(),
);
if hwnd.is_null() {
return;
}
SetTimer(hwnd, IDT_TIMER as UINT_PTR, 2000, None);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
let mut msg: MSG = std::mem::zeroed();
while GetMessageW(&mut msg, null_mut(), 0, 0) > 0 {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
}
unsafe extern "system" fn wnd_proc(
hwnd: HWND,
msg: UINT,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
static mut TIME_STR: [u16; 64] = [0; 64];
match msg {
WM_CREATE => {
get_time_string(&mut TIME_STR);
SetTimer(hwnd, IDT_TIMER as UINT_PTR, 2000, None);
0
}
WM_TIMER => {
if wparam == IDT_TIMER {
get_time_string(&mut TIME_STR);
InvalidateRect(hwnd, std::ptr::null(), TRUE);
}
0
}
WM_PAINT => {
let mut ps: PAINTSTRUCT = std::mem::zeroed();
let hdc = BeginPaint(hwnd, &mut ps);
let rect: RECT = {
let mut r = std::mem::zeroed();
GetClientRect(hwnd, &mut r);
r
};
DrawTextW(
hdc,
TIME_STR.as_ptr(),
TIME_STR.iter().position(|&c| c == 0).unwrap_or(TIME_STR.len()) as i32,
&rect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
);
EndPaint(hwnd, &ps);
0
}
WM_DESTROY => {
KillTimer(hwnd, IDT_TIMER as UINT_PTR);
PostQuitMessage(0);
0
}
_ => DefWindowProcW(hwnd, msg, wparam, lparam),
}
}
fn get_time_string(buf: &mut [u16; 64]) {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let tm = unsafe { *localtime(&now as *const u64 as *const i64) };
let mut time_str = [0u8; 64];
unsafe {
strftime(
time_str.as_mut_ptr() as *mut i8,
time_str.len(),
b"%Y-%m-%d %H:%M:%S\0".as_ptr() as *const i8,
&tm,
);
}
let utf16: Vec<u16> = OsStr::from_bytes(&time_str)
.encode_wide()
.take_while(|&c| c != 0)
.collect();
for (i, &c) in utf16.iter().enumerate() {
buf[i] = c;
}
buf[utf16.len()] = 0;
}
fn to_wstring(s: &str) -> Vec<u16> {
OsStr::new(s)
.encode_wide()
.chain(Some(0))
.collect()
}
总结
Rust 在保持高性能的同时提供了更高的安全性、开发效率和可维护性,是现代桌面开发的优秀选择。