Ownership of extra window memory in WinAPI


#1

I’m new to Rust, so forgive me if this is more a more rudimentary issue than I realize.

I’m working on a program that uses WinAPI. I’m trying to make use of the extra window memory on my main window. For those unfamiliar with WinAPI, extra window memory works like this: when calling the function that creates a window, one can request up to 40 bytes of additional memory, which are appended to the end of the memory range the operating system reserves for the window. Once the window has been created, one can then call SetWindowLongPtr in order to select any isize-sized chunk of this memory and fill it with anything one chooses, and likewise call GetWindowLongPtr to retrieve it in isize-sized chunks.

What I would like to do is use the memory to store the address of a struct that contains everything I need, so that I don’t have to worry about the possibility of the struct overflowing the limit of 40 bytes as I add fields over the course of expanding the program. I would like to be able to mutate this struct from within the window’s own window procedure. First of all, what kind of pointer would it be most appropriate to treat the memory as - reference, raw pointer, Box, or something else? And if Box is best, what is the best way to convert to and from the isize that SetWindowLongPtr requires and GetWindowLongPtr returns? I might have more questions depending on the answers.


#2

When I did this, I used Arc<Mutex<_>>, so I could guarantee the memory wouldn’t be deallocated while I was using it. I can try to dig up more details later if you need them, but it shouldn’t be too hard.


#3

The equivalent in a single-threaded context would just be Rc<_>, right? I’ll have to think about what the implications of the reference-counting are.

It would be helpful to see what the casting looks like.


#4

Yeah, but are you absolutely 100% certain no one is going to read that pointer from another thread? Because if you’re not, there’s really no point in not using the thread-safe version instead.

Looking at the old code, the way I set it up was that I had a WindowUserData structure, and just did a cast from the pointer GWLP_USERDATA gave me. The WindowUserData contained both a magic number (for sanity checking), and an Arc to the actual data I cared about. If you don’t understand how to do casting in Rust yet, I’d recommend not trying to do FFI until you do. FFI means you have no safety net, and it is really easy to blow your legs off and not realise.

Not sure what to point you to; the Rust Book as a first stop, possibly followed by the Rustonomicon or the Rust FFI Omnibus.