首先需要安装32位编译环境:
rustup target add i686-pc-windows-msvc
以Release方式编译32位目标程序:
cargo build --target i686-pc-windows-msvc --release
在VS开发环境中想要修改目标编译文件类型非常简单,只需要在项目属性里面点一点就能修改。但在Rust中我目前还没找到可以“愉快”的修改目标编译文件的子系统属性。希望以后可以在`Cargo.toml`中有所呈现。
使用编译命令行来进行指定,(SUBSYSTEM:CONSOLE => SUBSYSTEM:WINDOWS)
cargo rustc -- -C link-args=/SUBSYSTEM:WINDOWS
如果想要目标Rust程序运行在Windows XP上面,则:
cargo rustc --target=i686-pc-windows-msvc -- -C link-args=/SUBSYSTEM:WINDOWS,5.01
如果想要目标Rust程序编译成完全独立的程序(VS中使用/MT),使用附加参数-Ctarget-feature=+crt-static
,则:
cargo rustc --release --target=i686-pc-windows-msvc -- -Clink-args=/SUBSYSTEM:WINDOWS -Ctarget-feature=+crt-static
该命令编译的目标程序将会是 发布版本、32位、Windows子系统,去除CRT运行库的样本。
微软放出了自己的开源库,Rust for Windows(windows-rs), 并且还有配套的用于搜索API目录结构的网站,Bindings for windows; 这是我搭建的镜像网站, 示例视频:https://www.youtube.com/watch?v=LajquCjHXK4&feature=youtu.be
使用Rust for Window
开发的代码片段示例:
use bindings::
{
windows::Result, windows::win32::gdi::ValidateRect,
windows::win32::menus_and_resources::
{
LoadCursorA, HMENU
},
windows::win32::system_services::
{
GetModuleHandleA, CS_HREDRAW, CS_VREDRAW, CW_USEDEFAULT, HINSTANCE, IDC_ARROW, LRESULT,
WM_DESTROY, WM_PAINT, WS_OVERLAPPEDWINDOW, WS_VISIBLE,WM_LBUTTONDOWN
},
windows::win32::
{
gdi::UpdateWindow, system_services::MB_OK, windows_and_messaging::
{
CreateWindowExW, DefWindowProcW, DispatchMessageW,
GetMessageA, GetMessageW, HWND, LPARAM, MSG,
MessageBoxW, PostQuitMessage, RegisterClassW,
TranslateMessage, WNDCLASSW, WPARAM
}
}
};
use std::ptr::{null, null_mut};
extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
{
unsafe
{
match message as i32
{
WM_LBUTTONDOWN =>
{
println!("lButton down. {:?}, {:?}", wparam, lparam);
LRESULT(0)
}
WM_PAINT =>
{
println!("WM_PAINT");
ValidateRect(window, null());
LRESULT(0)
}
WM_DESTROY =>
{
println!("WM_DESTROY");
PostQuitMessage(0);
LRESULT(0)
}
_ =>
{
DefWindowProcW(window, message, wparam, lparam)
}
}
}
}
fn main()
{
unsafe
{
WinMain(HINSTANCE(0), HINSTANCE(0), null(), 0);
}
}
pub unsafe extern "system" fn WinMain(instance:HINSTANCE, _:HINSTANCE, _ : *const i8, _ : i32) -> i32
{
let instance = HINSTANCE(GetModuleHandleA(null()));
debug_assert!(instance.0 != 0);
let className = "window\0";
let windowTitle = "Window created from Rust.\0";
let mut wc = WNDCLASSW::default();
wc.h_cursor = LoadCursorA(HINSTANCE(0), IDC_ARROW as *mut i8);
wc.h_instance = instance;
let class_name : Vec = className.encode_utf16().collect();
wc.lpsz_class_name = class_name.as_ptr() as *mut u16;
wc.lpfn_wnd_proc = Some(wndproc);
wc.style = (CS_HREDRAW | CS_VREDRAW) as u32;
wc.h_cursor = LoadCursorA(HINSTANCE(0), IDC_ARROW as *const i8);
// wc.lpsz_class_name = className.encode_utf16().collect();
let _atom = RegisterClassW(&wc);
debug_assert!(_atom != 0);
let window_name : Vec = windowTitle.encode_utf16().collect();
let windowHandle = CreateWindowExW(
0,
class_name.as_ptr(),
window_name.as_ptr(),
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640, 480,
HWND(0),HMENU(0), instance, null_mut());
UpdateWindow(windowHandle);
let mut msg = MSG::default();
while GetMessageW(&mut msg, windowHandle, 0, 0).into() {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
0
}