Top Related Projects
Rust for Windows
SDL2 bindings for Rust
Raw bindings to platform APIs for Rust
DEPRECATED, use https://github.com/gtk-rs/gtk3-rs repository instead!
Quick Overview
winapi-rs is a Rust library that provides bindings to Windows API functions. It aims to offer a safe and idiomatic Rust interface to the Windows API, allowing Rust developers to interact with Windows-specific functionality more easily and safely.
Pros
- Provides safe Rust wrappers for Windows API functions
- Extensive coverage of Windows API, including both common and less-used functions
- Actively maintained and regularly updated
- Allows for writing Windows-specific applications in Rust
Cons
- Limited to Windows platforms, reducing cross-platform compatibility
- Learning curve for developers not familiar with Windows API
- Some functions may still require unsafe code blocks
- Documentation can be sparse for less common API functions
Code Examples
- Getting the current process ID:
use winapi::um::processthreadsapi::GetCurrentProcessId;
fn main() {
let pid = unsafe { GetCurrentProcessId() };
println!("Current process ID: {}", pid);
}
- Creating a message box:
use winapi::um::winuser::{MessageBoxW, MB_OK};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
fn main() {
let title: Vec<u16> = OsStr::new("Hello").encode_wide().chain(Some(0)).collect();
let text: Vec<u16> = OsStr::new("Hello, World!").encode_wide().chain(Some(0)).collect();
unsafe {
MessageBoxW(std::ptr::null_mut(), text.as_ptr(), title.as_ptr(), MB_OK);
}
}
- Getting system metrics:
use winapi::um::winuser::{GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN};
fn main() {
let screen_width = unsafe { GetSystemMetrics(SM_CXSCREEN) };
let screen_height = unsafe { GetSystemMetrics(SM_CYSCREEN) };
println!("Screen resolution: {}x{}", screen_width, screen_height);
}
Getting Started
To use winapi-rs in your Rust project, add the following to your Cargo.toml
file:
[dependencies]
winapi = { version = "0.3", features = ["processthreadsapi", "winuser"] }
Then, in your Rust code, you can import and use the Windows API functions:
use winapi::um::winuser::MessageBoxW;
fn main() {
// Your code using Windows API functions
}
Remember to use unsafe
blocks when calling Windows API functions, as they are inherently unsafe in Rust's safety model.
Competitor Comparisons
Rust for Windows
Pros of windows-rs
- Official Microsoft support and maintenance
- More comprehensive coverage of Windows APIs
- Better integration with modern Rust practices and idioms
Cons of windows-rs
- Larger binary size due to more extensive API coverage
- Steeper learning curve for newcomers to Windows API development
Code Comparison
winapi-rs:
use winapi::um::winuser::MessageBoxW;
use std::ptr::null_mut;
unsafe {
MessageBoxW(null_mut(), wide_string!("Hello"), wide_string!("Title"), 0);
}
windows-rs:
use windows::Win32::UI::WindowsAndMessaging::MessageBoxW;
unsafe {
MessageBoxW(None, "Hello", "Title", Default::default());
}
The windows-rs example demonstrates a more idiomatic Rust approach, with better type safety and easier-to-read code. It doesn't require manual null pointer handling or explicit string conversion macros.
Both libraries serve the purpose of providing Rust bindings for Windows APIs, but windows-rs offers a more modern and officially supported solution. While winapi-rs has been a popular choice for many years, windows-rs is gaining traction due to its official backing and improved Rust integration. Developers should consider their specific needs and project requirements when choosing between the two libraries.
SDL2 bindings for Rust
Pros of rust-sdl2
- Cross-platform support for multiple operating systems
- Provides high-level abstractions for multimedia and game development
- Active community and frequent updates
Cons of rust-sdl2
- Larger dependency footprint
- May have performance overhead compared to direct API calls
- Requires linking to external SDL2 libraries
Code Comparison
winapi-rs:
use winapi::um::winuser::{MessageBoxW, MB_OK};
use std::ptr::null_mut;
unsafe {
MessageBoxW(null_mut(), wide_string!("Hello"), wide_string!("Title"), MB_OK);
}
rust-sdl2:
use sdl2::messagebox::show_simple_message_box;
sdl2::init().unwrap();
show_simple_message_box(sdl2::messagebox::MessageBoxFlag::INFORMATION,
"Title", "Hello", None).unwrap();
The winapi-rs example directly calls Windows API functions, while rust-sdl2 provides a cross-platform abstraction layer. winapi-rs offers more fine-grained control but is Windows-specific, whereas rust-sdl2 simplifies development across multiple platforms at the cost of some performance and flexibility.
Raw bindings to platform APIs for Rust
Pros of libc
- More comprehensive, covering multiple platforms (Unix-like systems, Windows, etc.)
- Part of the official Rust project, ensuring long-term maintenance and support
- Provides a unified interface for system calls across different operating systems
Cons of libc
- Less specialized for Windows-specific functionality
- May have a steeper learning curve for developers focusing solely on Windows development
- Potentially larger overhead due to cross-platform support
Code Comparison
winapi-rs:
use winapi::um::winuser::{MessageBoxW, MB_OK};
use winapi::um::winnt::LPCWSTR;
unsafe {
MessageBoxW(std::ptr::null_mut(), "Hello" as LPCWSTR, "Title" as LPCWSTR, MB_OK);
}
libc:
use libc::{c_int, c_char};
use std::ffi::CString;
unsafe {
libc::printf(CString::new("Hello, %s!\n").unwrap().as_ptr(), CString::new("World").unwrap().as_ptr());
}
The winapi-rs example demonstrates Windows-specific API usage, while the libc example shows a more general, cross-platform approach to system calls. winapi-rs provides a more idiomatic Rust interface for Windows programming, whereas libc offers a broader range of system functions across different platforms.
DEPRECATED, use https://github.com/gtk-rs/gtk3-rs repository instead!
Pros of gtk
- Cross-platform support for Linux, macOS, and Windows
- Extensive documentation and examples for Rust bindings
- Active community and frequent updates
Cons of gtk
- Larger dependency footprint
- Steeper learning curve for those unfamiliar with GTK
Code Comparison
gtk:
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow};
fn main() {
let app = Application::builder().build();
app.connect_activate(build_ui);
app.run();
}
winapi-rs:
use winapi::um::winuser::{CreateWindowExW, ShowWindow};
fn main() {
unsafe {
let hwnd = CreateWindowExW(/* params */);
ShowWindow(hwnd, /* params */);
}
}
The gtk example demonstrates a higher-level abstraction for creating a window, while winapi-rs requires more low-level interaction with the Windows API. gtk provides a more idiomatic Rust experience, but winapi-rs offers finer control over Windows-specific functionality.
gtk is better suited for cross-platform GUI development, while winapi-rs is specifically tailored for Windows systems. The choice between them depends on the project requirements, target platforms, and developer preferences.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
winapi-rs
Official communication channel: #windows-dev on the Rust Community Discord
This crate provides raw FFI bindings to all of Windows API. They are gathered by hand using the Windows 10 SDK from Microsoft. I aim to replace all existing Windows FFI in other crates with this crate through the "Embrace, extend, and extinguish" technique.
If this crate is missing something you need, feel free to create an issue, open a pull request, or contact me via other means.
This crate depends on Rust 1.6 or newer on Windows. On other platforms this crate is a no-op and should compile with Rust 1.2 or newer.
Frequently asked questions
How do I create an instance of a union?
Use std::mem::zeroed()
to create an instance of the union, and then assign the value you want using one of the variant methods.
Why am I getting errors about unresolved imports?
Each module is gated on a feature flag, so you must enable the appropriate feature to gain access to those items. For example, if you want to use something from winapi::um::winuser
you must enable the winuser
feature.
How do I know which module an item is defined in?
You can use the search functionality in the documentation to find where items are defined.
Why is there no documentation on how to use anything?
This crate is nothing more than raw bindings to Windows API. If you wish to know how to use the various functionality in Windows API, you can look up the various items on MSDN which is full of detailed documentation.
Can I use this library in no_std
projects?
Yes, absolutely! By default the std
feature of winapi
is disabled, allowing you to write Windows applications using nothing but core
and winapi
.
Why is winapi
's HANDLE
incompatible with std
's HANDLE
?
Because winapi
does not depend on std
by default, it has to define c_void
itself instead of using std::os::raw::c_void
. However, if you enable the std
feature of winapi
then it will re-export c_void
from std
and cause winapi
's HANDLE
to be the same type as std
's HANDLE
.
Should I still use those -sys
crates such as kernel32-sys
?
No. Those crates are a legacy of how winapi
0.2 was organized. Starting with winapi
0.3 all definitions are directly in winapi
itself, and so there is no longer any need to use those -sys
crates.
Example
Cargo.toml:
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }
main.rs:
#[cfg(windows)] extern crate winapi;
use std::io::Error;
#[cfg(windows)]
fn print_message(msg: &str) -> Result<i32, Error> {
use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
use std::ptr::null_mut;
use winapi::um::winuser::{MB_OK, MessageBoxW};
let wide: Vec<u16> = OsStr::new(msg).encode_wide().chain(once(0)).collect();
let ret = unsafe {
MessageBoxW(null_mut(), wide.as_ptr(), wide.as_ptr(), MB_OK)
};
if ret == 0 { Err(Error::last_os_error()) }
else { Ok(ret) }
}
#[cfg(not(windows))]
fn print_message(msg: &str) -> Result<(), Error> {
println!("{}", msg);
Ok(())
}
fn main() {
print_message("Hello, world!").unwrap();
}
Financial Support
Do you use winapi
in your projects? If so, you may be interested in financially supporting me on Patreon. Companies in particular are especially encouraged to donate (I'm looking at you Microsoft).
Top Related Projects
Rust for Windows
SDL2 bindings for Rust
Raw bindings to platform APIs for Rust
DEPRECATED, use https://github.com/gtk-rs/gtk3-rs repository instead!
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot