Archive: System: best practices for splitting a struct into its substructs?


System: best practices for splitting a struct into its substructs?
  I'm trying to figure out what the best practice would be to split a struct into its substructs/data.

E.g. say I have a struct in $0 that looks like this:
(NMHDR, dwFlags, RECT)

I can pass $0 directly to a macro / function / copy/paste bit of code to handle NMHDR. But let's say I have a similar macro / function /copy/paste bit of code to handle RECTs.. but I can't pass i t $0 because it's got the NMHDR and dwSomething in front.

I could be hacky and offset $0 by the size of NMHDR+dwSomething, but I'd imagine that may be architecture-specific and, well, hacky.

But what would be the best practice? Put the relevant bits on the stack, pop into a newly allocated struct, free that struct when done?
e.g.


System::Call "*$0(i, i, i, i, i.s, i.s, i.s, i.s)" /* presuming I don't care about nmhdr/dwFlags */

>System::Alloc "*(is, is, is, is).r1"
>***91;parse the RECT struct in $1 now***93;
>System::Free $1
>
Or is there a more appropriate method?

Yes, a offset would be architecture-specific (32 and 64 bit, and 64bit NSIS, well, lets get unicode merged first)

But when you do System::Call "*$0(i, i, i, i... , this is actually the same as a offset and would not work as a native 64 bit app. When 2.47 comes out, you would be able to use p tho.

You could add a helper macro: !macro GetStructMemberPtr_NMHDR::RECT in_baseptr outvar_adjustedptr (You might want a shorter name ;) and NMHDR is probably not the correct name, you are probably working with the listview specific struct or something like that)

...or just a define for the offset. You could have a macro that created struct offset defines:
!macro CreateStructOffsetDefine symname p i32 i16 i8
ex !insertmacro CreateStructOffsetDefine NMLVDISPINFO::LVITEM 2 1 0 0


But would I then use that defined offset in exactly the hacky manner that I mentioned? :o

Right now I"m using the out-to-stack, create-from-stack, destroy-creation method, but if the hacky method is every bit as valid, I'd happily use that instead %)


Yes, but with a define, it is in a header somewhere and you can use !ifdef NSIS_WIN64 when the time comes ;)

But like I said, when 2.47 comes out, you can use p and then system::call *$x(... will work without hacks


Yes, of course with a define :)
(or rather, multiple defines.. defining the offsets within structs for other structs)

I'll have to await the details of 2.47 and how p kicks in here :)