Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » siezof(...)

This thread is locked; no one can reply to it. rss feed Print
siezof(...)
William Labbett
Member #4,486
March 2004
avatar

hi,

need some help again please. I've got a struct here :-

#SelectExpand
1struct F_REP 2{ 3 char png_filename[ MAX_LENGTH_FOR_FRD_STRING ]; 4 int32_t type; 5 int32_t squares_wide_on_map; 6 int32_t squares_high_on_map; 7 int32_t x_offset; /* the x offset from the top left square indicating where the feature is positioned */ 8 int32_t y_offset; 9 int32_t number_of_bitmaps; 10 int32_t ticks_per_frame; 11 int32_t line_in_animation_specs_file; 12 int32_t altitude; 13 14 int32_t shadow_x_offset; 15 int32_t shadow_y_offset; 16 17 int32_t c_x_offset; 18 int32_t c_y_offset; 19 20 21 uint8_t attributes; 22 23 uint8_t tint_value; 24 25};

When I write the struct's data to a file I keep a check on how many bytes are written and then make a check :

#SelectExpand
1if(bw != MAX_LENGTH_FOR_FRD_STRING + 13 * 4 + 2) 2 { 3 pf(" write_f_rep_() : bytes written unexpected. error writing to file.\n"); 4 return -1; 5 } 6 7 if(sizeof(F_REP) != bw) 8 { 9 pf("MAX_LENGTH_FOR_FRD_STRING + 13 * 4 + 2 = %d.\n", MAX_LENGTH_FOR_FRD_STRING + 13 * 4 + 2); 10 pf("sizeof(F_REP) = %d.\n", sizeof(F_REP)); 11 pf("bytes written = %d.\n", bw); 12 13 pf(" write_f_rep_() : something not right with amount of bytes written to file.\n"); 14 return -1; 15 }

Here's what it outputs :

MAX_LENGTH_FOR_FRD_STRING + 13 * 4 + 2 = 154.
sizeof(F_REP) = 156.
bytes written = 154.
write_f_rep_() : something not right with amount of bytes written to file.
edit_features() : couldn't write added F_REP to file.
Press any key to continue . . .

I don't understand why the sizeof(F_REP) is 2 bytes more than 154 (MAX_LENGTH_FOR_FRD_STRING + 13 * 4 + 2).

If someone keep help me understand that would be great.

Trent Gamblin
Member #261
April 2000
avatar

Structs are often padded for performance reasons. There's probably a #pragma or command line switch to turn it off.. but I hope you know there can be problems with writing structs to a file all at once, instead of one variable at a time in a given byte order. If two machines have different byte orders, the one that reads them will read them different from the one that wrote them.

William Labbett
Member #4,486
March 2004
avatar

Thanks Trent.

Structs are often padded for performance reasons. There's probably a #pragma or command line switch to turn it off..

I see. 156 is a mutliple of 4 so I guess there's an extra 2 bytes added/

Quote:

but I hope you know there can be problems with writing structs to a file all at once, instead of one variable at a time in a given byte order.

I'm using the al_fwrite... functions which I presume solves that issue.

Except that there's no *le function for writing 1 byte types :/

gnolam
Member #2,030
March 2002
avatar

Except that there's no *le function for writing 1 byte types :/

Because there's no byte ordering when there's just one byte. :)

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

OnlineCop
Member #7,919
October 2006
avatar

Your struct will be 32-bit aligned (4-byte).

All of your int32_t and uint32_t are already 4-byte aligned, so those are fine. But the two uint8_t only equal 16 bytes, and as Trent said, your compiler optimizes the struct and pushes up 2 more bytes onto that. So if you changed those both to uint16_t, you will not notice any size difference. Or, if you wanted to add an extra uint16_t at the end as a padding buffer, that is something we do at work to keep them 4-byte aligned as well.

William Labbett
Member #4,486
March 2004
avatar

gnolam said:

Because there's no byte ordering when there's just one byte.

;D I think I was thinking that the bits are the opposite way around with le and be

OnlineCop said:

Or, if you wanted to add an extra uint16_t at the end as a padding buffer, that is something we do at work to keep them 4-byte aligned as well.

Thanks for that tip. Think I'll do so..

Oscar Giner
Member #2,207
April 2002
avatar

but I hope you know there can be problems with writing structs to a file all at once, instead of one variable at a time in a given byte order.

I'm using the al_fwrite... functions which I presume solves that issue.

Allegro doesn't magically know what members your struct has. So no, what Trent says still applies. You have to al_fwrite each member individually.

Trent Gamblin
Member #261
April 2000
avatar

There are separate functions called al_fwrite32le and so on, so I think he's got the idea.

William Labbett
Member #4,486
March 2004
avatar

Thanks guys.

Thought I could save starting a new thread by asking a quick question here :-

Quote:

C:\Users\0_0\Desktop\2_tone_pattern>mingw32-make
:
building libdinkleblot.dll
:
gcc -Wall -shared -o libdinkleblot.dll tesselating_pattern.o torus_code.o south_
code_westwards.o south_code_eastwards.o save_invalid_pattern.o north_code_west.o
helper_functions.o gradient.o can_go_two_above.o can_go_north_of.o
-lallegro-5.0.1-md -lallegro_primitives-5.0.1-md -lallegro_ima
ge-5.0.1-md
:
building libdinkleblot.a
:
ar rcs libdinkleblot.a tesselating_pattern.o torus_code.o south_code_westwards.o
south_code_eastwards.o save_invalid_pattern.o north_code_west.o helper_function
s.o gradient.o can_go_two_above.o can_go_north_of.o
-lallegro-5.0.1-md -lallegro_primitives-5.0.1-md -lallegro_image-5.0.1-md -L C
:\MinGW\lib
ar: -lallegro-5.0.1-md: No such file or directory
mingw32-make: *** [dinkleblot_dll] Error 1

C:\Users\0_0\Desktop\2_tone_pattern>

Seems like it can't find liballegro-5.0.1-md.a but I've checked that it's in C:\MinGW\lib and it is so I'm puzzled.

It finds it when it builds the dll.

Oscar Giner
Member #2,207
April 2002
avatar

You don't link to any library when you create a library. So remove al -l parameters to ar.

William Labbett
Member #4,486
March 2004
avatar

Thanks Oscar.

Here's what my Makefile looks like :

Quote:

OBJECT_DIR = ../object_code

LD_FLAGS = -lallegro-5.0.1-md -lallegro_primitives-5.0.1-md -lallegro_image-5.0.1-md

OBJECT_FILES = tesselating_pattern.o \
torus_code.o \
south_code_westwards.o \
south_code_eastwards.o \
save_invalid_pattern.o \
north_code_west.o \
helper_functions.o \
gradient.o \
can_go_two_above.o \
can_go_north_of.o


dinkleblot_dll : $(OBJECT_FILES)
@echo :
@echo building libdinkleblot.dll
@echo :
gcc -Wall -shared -o libdinkleblot.dll $(OBJECT_FILES) $(LD_FLAGS)
@echo :
@echo building libdinkleblot.a
@echo :
ar rcs libdinkleblot.a $(OBJECT_FILES)

%.o : %.c
@echo :
@echo building $@
@echo :
gcc -c $< -o $@

Should I also remove the linked .a files with the building of the dll ?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Should I also remove the linked .a files with the building of the dll ?

No, when you build a dll, you need to link it to the libraries it uses. Think of it as a standalone executable. With a static library, think of it as a collection of .o files - it needs to be linked later.

William Labbett
Member #4,486
March 2004
avatar

So a dll must have all the functions it calls resolved when compiled ...

Thanks.

Go to: