From: "A. Sinan Unur" Newsgroups: comp.os.msdos.djgpp Subject: Re: Problem with Packed structs Date: Sun, 13 Apr 1997 08:23:54 -0400 Organization: Cornell University http://www.cornell.edu Lines: 81 Sender: asu1 AT cornell DOT edu (Verified) Message-ID: <3350D05A.3B4D@cornell.edu> References: <9704121940 DOT AA20198 AT eed DOT miee DOT ru> Reply-To: asu1 AT cornell DOT edu NNTP-Posting-Host: cu-dialup-0052.cit.cornell.edu Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Oleg Yu. Polyanski wrote: >>> (1) When calling an interrupt, I often need to declare a packed >> struct which matches the layout of the data needed or provided by the >> interrupt. this is mostly out of curiousity, i am not trying to take sides in the packed vs not packed. however, i read that the order of the fields in a packed struct need not remain the same from one version of the compiler to the other. this means using packed structs may not be safe for interrupt related routines. playing around with my neverending netbios project (where i had copies of network control blocks in my memory space which were copied to the approriate location in dos memory before invoking the interrupt), i thought one 'solution' to this would be to define a number of offsets instead of the structure itself. for example, instead of using /* Network Control Block (NCB) */ typedef struct { BYTE cmd; /* command code */ BYTE ret_code; /* return code */ BYTE lsn; /* local session number */ BYTE ncb_num; /* "ncb_num" ADD NAME */ WORD io_off; /* offset of the IO buffer */ WORD io_seg; /* segment of the IO buffer */ WORD len; /* length of data in the buffer */ BYTE rmt_name[16]; /* name of remote system to call */ BYTE lcl_name[16]; /* name of the local machine */ BYTE rec_to; /* receive timeout in 1/2 seconds */ BYTE snd_to; /* send timeout in 1/2 seconds */ WORD post_off; /* offset of the POST routine */ WORD post_seg; /* segment of the POST routine */ BYTE lana; /* lan adapter no: 0x00 - 0x03 */ BYTE cmp_code; /* completion code */ BYTE rsrv[14]; /* reserved area of 14 BYTEs */ }__attribute__((packed)) NCB; and then copying it to the allocated dos memory (using movedata or dosmemput), one could define: /* Offsets of NCB fields */ #define O_CMD 0x00 #define O_RET_CODE 0x01 #define O_LSN 0x02 #define O_NCB_NUM 0x03 #define O_IO_OFF 0x04 #define O_IO_SEG 0x06 #define O_LEN 0x08 #define O_RMT_NAME 0x0A #define O_LCL_NAME 0x1A #define O_REC_TO 0x2A #define O_SND_TO 0x2B #define O_POST_OFF 0x2C #define O_POST_SEG 0x2E #define O_LANA 0x30 #define O_CMP_CODE 0x31 #define O_RSRV 0x32 using the former, i would setup each field and then copy the struct to conventional memory. using the latter, i would just do (for example) _farpokeb(_dos_ds, linear_addr_of_ncb+O_REC_TO, 10); does anyone care to comment on this? basically, i am beginning to feel like it actually makes sense because (i) it completely obviates depending on the packing order and (ii) reduces bookkeeping associated with copies floating around. and i might even be inclined to write my first C++ stuff to make this look beautiful. (inline member functions vs macros.) -- Sinan ******************************************************************* A. Sinan Unur WWWWWW |--O+O mailto:sinan DOT unur AT cornell DOT edu C ^ http://www.people.cornell.edu/pages/asu1/ \ ~/ *******************************************************************