The idea was to give you the size of a structure in bytes of a structure:...
I need these sizes to user Raku's NativeCall.
T,
The idea was to give you the size of a structure in bytes of a structure:...
I need these sizes to user Raku's NativeCall.
That won't be possible I'm afraid. "sizeof" and "offsetoff" are pseudo-commands, resolved at compile, not runtime.
Regards,
Rudy Wieser
T,
How'd he come up with them?
"Them" ? I'm not sure what you are referring to.
If you mean the lines you posted as "the result", than you should know its a misnomer. Its not the *result*, its just how you ask for those (already existing!) constants.
Take a look
typedef struct _WTS_SESSION_INFOA {
DWORD SessionId; # 4 bytes
LPSTR pWinStationName; # 4 or 8 bytes
WTS_CONNECTSTATE_CLASS State; # 4 bytes
}
(assuming that you are on a 32-bit machine that LPSTR is going to be 32 bit too)
You can go thru the offsets and sizes yourself :
The first field thats declared is "SessionId", of type DWORD, which is 4 bytes. As its the first field its located at offset 0.
The second field thats declared is "pWinStationName", of type LPSTR, which
is (also) 4 bytes. Its offset is the previous fields offset plus its size*, being 0 + 4, so its at offset 4.
The third field is "State" of type WTS_CONNECTSTATE_CLASS. Now it gets tricky, as you have to find that type back somewhere (in the multitude of
*.h (header files) ) and figure out what its size is. Lets assume 4 bytes (its just a DWORD in disguise). Its offset is again the previous fields offset plus its size, being 4 + 4, so its at offset 8.
The size of the whole structure is ofcourse (again) the offset of the last field plus its size, being 8 + 4, so it is 12 bytes long.
And that matches the comment after the first line in the result : "12 in
x86"
But remember that "*" that I tagged onto that "plus its size" ? Yeah, here is the thing: machines are a fussy about where start of its data pieces should be. There is a thing called "alignment".
Lets again take a look and assume we are now on a 64-bit machine. It
expects an alignment of 8. The "SessionId" field will still be just 4 bytes. So, how is it that the "pWinStationName" field after it is at
offset 8 ? Thats where padding comes in : it just fills out the space until the next allowed offset :
On a 64-bit machine :
(best viewed with a fixed width font. Copy it into notepad ?)
typedef struct _WTS_SESSION_INFOA {
DWORD SessionId; # 4 bytes - padding needed
DWORD ? // the padding. Unnamed, unused
LPSTR pWinStationName; # 8 bytes - No padding
WTS_CONNECTSTATE_CLASS State; # 4 bytes - padding needed
DWORD ? // the padding. Unnamed, unused
}
And now the structure matches the comments in the "result" in its full, including the "24 in x64" remark from the first line. :-)
Mind you, not all functions expect the data to be aligned. But for those
who do the above is how it works. And by the way, although it was not relevant to the above structure (it fits just fine) the x86 has an alignment of 4. IOW, if the first field would have been a byte it would be followed by, on an x86 machine, a padding of 3 bytes
Hope that helps.
... but you still need to do all that work by hand - or put the structure in a compiler and let it output those values ofcourse.
Regards,
Rudy Wieser
P.s.
That alignment also means that your structure-storage needs to be placed at
a multiple of that alignment value. If you don't the function trying to use will just throw an "bad argument" error. Don't ask me how I know that. :-)
How'd he come up with them?
Thank you!
I plan on printing out the contents of the structure
byte by byte and see what I find. I will presalt
the result with 0xFF and see what agets changed.
T,
Thank you!
You're welcome. :-) And I assume that was the information you wher
missing
I plan on printing out the contents of the structure
byte by byte and see what I find. I will presalt
the result with 0xFF and see what agets changed.
Good idea.
A suggestion though : first look at the structures bytes when you have not given the fields a value. If you get anything else than a single byte value back than "memfill" the whole structure with a certain value first, and only than put stuff ito the fields (possibly also memfill-ing each of them, preferrably with a different value. Makes it easier to see where one field ends and the padding or the next field starts).
Regards,
Rudy Wieser
T,
The variable I am sending will be created with
backfill:
my $SessionArray = CArray[BYTE].new( 0xFF xx $Length );
Ah yes. You're not creating the structure itself, you create some space for it and than cast that $SessionArray pointer to a WTS_SESSION_INFOA one (so you can access its fields).
That works too. :-)
Is that stil C, or Raku ?
Regards,
Rudy Wieser
The variable I am sending will be created with
backfill:
my $SessionArray = CArray[BYTE].new( 0xFF xx $Length );
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 379 |
Nodes: | 16 (2 / 14) |
Uptime: | 42:17:48 |
Calls: | 8,141 |
Calls today: | 4 |
Files: | 13,085 |
Messages: | 5,857,793 |