0

I'm trying to go through all windows (using Windows API) and get a list of the windows, but when I try to pass through a vector as a LPARAM then I get an error:

  1. non-primitive cast: *mut Vec<isize> as LPARAM an as expression can only be used to convert between primitive types or to coerce to a specific trait object

Code:

unsafe {
    let windows: Vec<isize> = vec![];
    let _ = WindowsAndMessaging::EnumWindows(Some(enum_window), &mut windows as *mut Vec<isize> as LPARAM).ok();
};
IInspectable
  • 46,945
  • 8
  • 85
  • 181
YummyOreo
  • 15
  • 3
  • Standard winapi calls can't take closures. – Michael Chourdakis Nov 25 '22 at 02:47
  • If it can't, then how do I pass a LPARAM – YummyOreo Nov 25 '22 at 02:57
  • @MichaelChourdakis there are no closures in the question, so I don't understand your comment. – Jmb Nov 25 '22 at 07:34
  • Please [edit](https://stackoverflow.com/posts/74567876/edit) your question to add a full [mre]. In particular what is `enum_windows` and where does `WindowsAndMessaging::EnumWindows` come from? The only `EnumWindows` I could find in `winapi` is [`winuser::EnumWindows`](https://docs.rs/winapi/0.3.9/winapi/um/winuser/fn.EnumWindows.html)… – Jmb Nov 25 '22 at 07:37
  • Does this answer your question: https://stackoverflow.com/questions/38995701/how-do-i-pass-a-closure-through-raw-pointers-as-an-argument-to-a-c-function ? – Jmb Nov 25 '22 at 07:57
  • 1
    [`LPARAM`](https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/struct.LPARAM.html) isn't a primitive type, so the cast fails. Use this instead: `LPARAM(&mut windows as *mut Vec as isize)` to construct an `LPARAM` that wraps a pointer. – IInspectable Nov 25 '22 at 11:16

1 Answers1

2

The error diagnostic contains two vital pieces of information:

  1. The expression that failed to compile
    *mut Vec<isize> as LPARAM
    
  2. The language rule that's being violated
    an as expression can only be used to convert between primitive types
    

Either one is spot-on. With any *mut _ a primitive type, it necessarily means that LPARAM isn't. And that is correct, too. Like most types that appear in the transformed API surface exposed by the windows crate, LPARAM follows the newtype idiom.

This prevents common errors where different types share the same underlying type (e.g. HWND and HDC), but also requires that clients construct values of the wrapper type. Casting won't work, as it would with the winapi or windows-sys crates (that use type aliases for primitive types instead).

The second argument to EnumWindows needs to be

LPARAM(&mut windows as *mut Vec<isize> as isize)
IInspectable
  • 46,945
  • 8
  • 85
  • 181