Page 1 of 1
pb4.30[b4] RtlInitUnicodeString error in x64 , ok in x32
Posted: Mon Dec 01, 2008 4:26 pm
by bingo
Code: Select all
Structure UNICODE_STRING
usLength.w
usMaximumLength.w
usBuffer.i
EndStructure
pu.UNICODE_STRING
Procedure Ansi2Uni(ansi.s)
SHStrDup_(@ansi,@myuni.i)
ProcedureReturn myuni
EndProcedure
testunistring.i = Ansi2Uni("test")
Debug testunistring ;ok
RtlInitUnicodeString_(@pu,testunistring)
Debug pu\usLength ; = 8
Debug pu\usMaximumLength ; = 10
Debug testunistring ; but 0 in x64 !?
Debug pu\usBuffer
Debug PeekS(pu\usBuffer) ; = t , but error in x64
pointer of 'testunistring' is NULL after RtlInitUnicodeString (x64) :roll:
it works in x32 ...
Posted: Mon Dec 01, 2008 4:39 pm
by freak
Just a a structure alignment problem. Use this one and it works:
Code: Select all
Structure UNICODE_STRING
usLength.w
usMaximumLength.w
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
_alignment.l
CompilerEndIf
usBuffer.i
EndStructure
Posted: Mon Dec 01, 2008 6:25 pm
by bingo
thanks ! but where is this documented ???

Posted: Mon Dec 01, 2008 6:49 pm
by Fred
On x64, every C structures fields of 8 bytes (pointers, quad) are padded on a 8 bytes boundary.
Posted: Mon Dec 01, 2008 9:23 pm
by Mistrel
Maybe I'm not understanding something. Wouldn't the .i in the structure compile to 8 bytes instead of 4 automatically on an x64 operating system?
Posted: Mon Dec 01, 2008 9:25 pm
by Demivec
Mistrel wrote:Maybe I'm not understanding something. Wouldn't the .i in the structure compile to 8 bytes instead of 4 automatically on an x64 operating system?
@Mistrel:
on x64 (i),(q),(*) need to align on 8 byte boundary
2(w) + 2(w) + 8(i) = (i) is not aligned on 8 byte boundary
2(w) + 2(w) +4(l) + 8(i) = (i) is aligned on 8 byte boundary
Posted: Mon Dec 01, 2008 9:26 pm
by Fred
You're right. And as the 2 fields before it are 2 words (2x2 = 4), the .i will be at the offset '4', which is not valid on x64. It needs to be on a 8 bytes boundary offset (so you add a 4 bytes padding).
If you have a structure like that:
Code: Select all
Structure x
a.b
b.i ; At offset 1, not good on x64
EndStructure
you will need to pad it like that:
Code: Select all
Structure x
a.b
pad.b[7]
b.i ; At offset 8, ok on x64
EndStructure
Note, that it is needed only for 8 bytes field size (for 4 bytes fields size, you need to be on 4 byte boundary tough).
Posted: Mon Dec 01, 2008 11:18 pm
by Mistrel
After reading about data structure alignment I understand now how it works. On x86 processors:
Wikipedia wrote:.. the x86 architecture originally did not require aligned memory access and still works without it
I also read that it's not uncommon for the compiler to add padding automatically. Will PureBasic support something like this?
http://en.wikipedia.org/wiki/Data_structure_alignment
Posted: Mon Dec 01, 2008 11:34 pm
by Fred
I don't think we will introduce this, as automatic structure padding is somewhat tricky. You will have to know what to do anyway, so just explictely pad it and it you're done. Note: C compiler has the #pragma pack() directive which tells how to pad a structure, and when misused it leds to very hard to spot bugs.
Posted: Thu Dec 04, 2008 12:26 am
by Rescator
I've always tried to pair up words and bytes so that there are 4byte alignments out of habit really. I guess I'll have to consider pairing things up on 8bytes where possible then. (usually no harder than moving vars around in a structure and add a reserved here and there

)