-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dart:ffi] sizeOf with wrong result #45239
Comments
This is expected behavior. C also rounds up the size to alignment. See this example. We're already tracking packed structs, closing this issue. |
I have no idea why godbot.org have a 16 result. Maybe related to
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; |
@dcharkes @mannprerak2 This is NOT expected behavior with MSVC. Could you re-open it? |
@Sunbreak windows is using packed structs by having Having size 16 is expected without packing, and size 14 is expected behavior with packing. |
BITMAPFILEHEADER bmpFIH = {0};
bmpFIH.bfType = ( (WORD) ('M' << 8) | 'B');
bmpFIH.bfSize = nImageSize + sizeof(BITMAPFILEHEADER);
bmpFIH.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*dwPaletteSize);
fwrite(&bmpFIH, 1, sizeof(BITMAPFILEHEADER), pFile);
fwrite(pDIB, 1, nImageSize, pFile);
fclose(pFile);
pFile = 0;
|
Yes, in the win32 API, the struct is packed. So using
@ffi.Packed(1) // This will make sizeOf<BITMAPFILEHEADER>() be 14 instead of 16.
class BITMAPFILEHEADER extends ffi.Struct {
@ffi.Uint16()
external int bfType;
@ffi.Uint32() // With packing this field is at offset 2 instead of 4 bytes.
external int bfSize;
@ffi.Uint16() // With packing this field is at offset 6 instead of 8 bytes.
external int bfReserved1;
@ffi.Uint16() // With packing this field is at offset 8 instead of 10 bytes.
external int bfReserved2;
@ffi.Uint32() // With packing this field is at offset 10 instead of 12 bytes.
external int bfOffBits;
} So, to my understanding, the problem you're facing right now is that |
So the only workaround for now is to hack like: dart-lang/native#506 ? // struct TW_VERSION {
// TW_UINT16 MajorNum;
// TW_UINT16 MinorNum;
// TW_UINT16 Language;
// TW_UINT16 Country;
// TW_STR32 Info;
// };
class TWVersion extends _TWStruct<TW_VERSION> {
static const _size = 2 + 2 + 2 + 2 + 34;
TWVersion._fromAddress(int ptr): super._fromAddress(ptr);
@override
void dispose() {
throw 'Undisposable nested structure';
}
@override
int get size => _size;
int get MajorNum => _getUint16(0);
set MajorNum(int i) => _setUint16(0, i);
int get MinorNum => _getUint16(2);
set MinorNum(int i) => _setUint16(2, i);
int get Language => _getUint16(4);
set Language(int i) => _setUint16(4, i);
int get Country => _getUint16(6);
set Country(int i) => _setUint16(6, i);
static const _InfoOffset = 2 + 2 + 2 + 2;
String get Info => _getString(_InfoOffset, 34);
set Info(String s) => _setString(_InfoOffset, s, 34);
} |
Yes, we're working on adding support for packed structs so that you don't have to do workarounds. P.S. |
Didn't know that. Thanks a lot! |
It is implemented in |
Reproduce
2.12.0-259.8.beta without NullSafety
2.13.0-30.0.dev with NullSafety
print(sizeOf<BITMAPFILEHEADER >())
results in 16, while it is 14The text was updated successfully, but these errors were encountered: