Closed
Description
Reproduce
2.12.0-259.8.beta without NullSafety
class BITMAPFILEHEADER extends ffi.Struct {
@ffi.Uint16()
int bfType;
@ffi.Uint32()
int bfSize;
@ffi.Uint16()
int bfReserved1;
@ffi.Uint16()
int bfReserved2;
@ffi.Uint32()
int bfOffBits;
}
2.13.0-30.0.dev with NullSafety
class BITMAPFILEHEADER extends ffi.Struct {
@ffi.Uint16()
external int bfType;
@ffi.Uint32()
external int bfSize;
@ffi.Uint16()
external int bfReserved1;
@ffi.Uint16()
external int bfReserved2;
@ffi.Uint32()
external int bfOffBits;
}
print(sizeOf<BITMAPFILEHEADER >())
results in 16, while it is 14
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
Sunbreak commentedon Mar 8, 2021
It turns out to be struct aligment:
bfType
is aligned tobfSize
with 4 bytesRelated: #38158, #43257
dcharkes commentedon Mar 8, 2021
This is expected behavior. C also rounds up the size to alignment. See this example.
We're already tracking packed structs, closing this issue.
Sunbreak commentedon Mar 8, 2021
I have no idea why godbot.org have a 16 result. Maybe related to
msvc(WINE)
. When running with real MSVC, it is 14 by defaultBITMAPFILEHEADER
is fromwingdi.h
: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheaderSunbreak commentedon Mar 9, 2021
@dcharkes @mannprerak2 This is NOT expected behavior with MSVC. Could you re-open it?
dcharkes commentedon Mar 9, 2021
@Sunbreak windows is using packed structs by having
#pragma pack(push, 1)
(win32 copy showing the pragma, godbolt reproduction).Having size 16 is expected without packing, and size 14 is expected behavior with packing.
Sunbreak commentedon Mar 9, 2021
https://github.com/twain/twain-samples/blob/e8f0151dd73519323d99a6e94841cb1e25d1d677/TWAIN-Samples/Twain_App_sample01/src/TwainApp.cpp#L942-L950
twain-samples
useBITMAPFILEHEADER
to write bmp files. 14 bytes works fine while 16 bytes makes the bmp file scrapped and unable to opendcharkes commentedon Mar 9, 2021
Yes, in the win32 API, the struct is packed. So using
dart:ffi
without packed structs support will produce problems.sizeOf< BITMAPFILEHEADER >()
will start producing the expected result when we land support for packed structs (#38158) and you change the struct definition to include that:So, to my understanding, the problem you're facing right now is that
dart:ffi
does not support packed structs yet. That's why I closed this issue as a duplicate of packed-structs support. Or am I misunderstanding you, and are you facing a different issue?Sunbreak commentedon Mar 9, 2021
So the only workaround for now is to hack like: dart-lang/native#506 ?
dcharkes commentedon Mar 9, 2021
Yes, we're working on adding support for packed structs so that you don't have to do workarounds.
P.S.
package:win32
already contains a workaround forBITMAPFILEHEADER
. You might be able to use / collaborate on that package.Sunbreak commentedon Mar 9, 2021
Didn't know that. Thanks a lot!
Sunbreak commentedon Mar 9, 2021
It is implemented in
win32: 2.x
, not inwin32: 1.7.4
before null-safety. What a pity