Windows-rs: Mapping `Option` to nullable types

Created on 22 May 2021  路  5Comments  路  Source: microsoft/windows-rs

As far as I'm aware, it isn't possible to reflect the nullable strings that are used in certain APIs with Option. For example, CreateProcessA takes many parameters that can be null to represent different configurations for creating the target process.

unsafe fn create_process(app: Option<&str>, cmd: Option<&str>, curdir: Option<&str>, ...) -> ... {
    let _ = CreateProcessA(
        app,
        cmd,
        ...,
        curdir,
        ...,
    );

    // ...
}

As you would expect, the None type would be implicitly converted to PSTR::NULL which I think might be useful when trying to write idiomatic code, especially libraries.

I _think_ something like this should be fairly easy to implement as some string types seem to have hand-written implementation details.

Ideally, this is probably something that could be handled for every nullable type and not just PSTR and friends, right?

enhancement

Most helpful comment

Thanks for the information! I was too stuck on trying to find a way to map my Option<&str> to an Option<PSTR> which I then thought I could unwrap to a PSTR::NULL on empty strings but I wasn't getting anywhere. The fleshed out example looks really nice and I'm excited to see progress in the future. Thanks for all of the work you put into the project, it's appreciated very much!

All 5 comments

Sorry for closing and then immediately reopening... had some struggles with my ability to use a computer.

I've just noticed #292, almost definitely related?

Hi Daniel, #292 is specifically about WinRT reference parameters. For CreateProcessA there is some support for Option but more work is needed. Here's a complete example:

use bindings::Windows::Win32::System::Threading::*;

fn main() {
    unsafe {
        CreateProcessA(
            "c:\\windows\\notepad.exe",
            None,
            std::ptr::null_mut(),
            std::ptr::null_mut(),
            false,
            Default::default(),
            std::ptr::null_mut(),
            None,
            &mut STARTUPINFOA {
                cb: std::mem::size_of::<STARTUPINFOA>() as _,
                ..Default::default()
            },
            &mut PROCESS_INFORMATION::default(),
        );
    }
}

As you can see, the optional string parameters can be replaced with None. I plan to also support this for the remaining optional pointer parameters when I get a moment. There's also https://github.com/microsoft/win32metadata/issues/433 to simplify the STARTUPINFOA initialization.

I'll keep this issue open to track the remaining usability issues. Ideally, we can write it more simply as follows:

CreateProcessA(
    "c:\\windows\\notepad.exe",
    None,
    None,
    None,
    false,
    Default::default(),
    None,
    None,
    &mut Default::default(),
    &mut Default::default(),
);

Thanks for the information! I was too stuck on trying to find a way to map my Option<&str> to an Option<PSTR> which I then thought I could unwrap to a PSTR::NULL on empty strings but I wasn't getting anywhere. The fleshed out example looks really nice and I'm excited to see progress in the future. Thanks for all of the work you put into the project, it's appreciated very much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AyashiNoCeres picture AyashiNoCeres  路  4Comments

kennykerr picture kennykerr  路  5Comments

bdbai picture bdbai  路  3Comments

rylev picture rylev  路  5Comments

kennykerr picture kennykerr  路  5Comments