On portable C programming (was: libraw1394 struct layouts...)

Jim Kuzdrall gnhlug at intrel.com
Thu Jan 8 08:20:12 EST 2009


On Thursday 08 January 2009 00:06, Ben Scott wrote:
> On Wed, Jan 7, 2009 at 11:31 PM,  <VirginSnow at vfemail.net> wrote:
> > So what's the recommended way to do this?
>
>   I dunno that there really is any really good way.

    There is a solution to the problem, I believe, if the structs are 
data structures that you wish to be common to several environments and 
processors.

    The problem is, as pointed out, that numeric values must be on 
certain byte boundaries for different processors.  Mixed in text does 
not, but it will end up on a boundary if it follows a number (float, 
double, integer, etc.).  Any mixed-in text requires padding that varies 
with the processor or compiler when the next number is reached.

    The solution starts with a program for which the structs are 
working.  These structs are then read, one element at a time, by a 
program that converts them to a "universal" format, creating a 
universal struct.  These functions are readily compiled on any system 
without any adjustments, as it turns out.

    Once created, the structs go into a "universal" struct library which 
can be used various ways, depending on your needs.  Your programs must 
explicitely access all structs via a pointer array, constructed each 
time the program loads.  The program which uses the struct first 
translates the universal struct to its native format.  Then it replaces 
the pointer the compiler put in the array with the location of the 
translated struct.

    You can allow all systems to access the struct library with the 
universal format functions to keep the structs up to date.  Or, if the 
values are static, just translate the universal struct library to 
several native libraries, which can be loaded in binary to their 
respective programs.

    So, what about these universal programs?  The problem is the numeric 
values.  A crude solution would create the universal struct entirely of 
ASCII by using printf(), strtol(), strtod(), etc.  (Don't use scanf(); 
it usually causes more problems than is solves.)

    A more elegant way was published in the "C/C++ Users Journal" 
January 1995, page 33, entitled "Transferring Numeric Values Between 
Computers" by (guess who) James A. Kuzdrall.  P. J. Plauger was editior 
and was enthralled by the universality of the technique.  Neither the 
numeric format of the host or the target computer need be known - 
bigendian/littleendian, 32bit/64bit, 2,s compliment/BCD, none of that 
changes the source code of the translation programs.

    The functions are fputi, fgeti, fputl, fgetl, fputf, fgetf.  fgetf 
translates to and from a float of 32-bits, which can be cast to native 
precision before storing in the native system.  If you need more float 
precision than 32-bits, the algorithm must be extended to double.

    If anyone is interested, I will see if I can find my copy of the 
article in text format and the source code for the functions.  You must 
be pretty conversant with numeric structures to follow the reasoning, 
but using the functions is easy.

Jim Kuzdrall

P.S. If anyone wants this numeric transfer technique as this month's 
topic for MerriLUG, let me know before noon today, 08 Jan, when the 
notice goes out.


More information about the gnhlug-discuss mailing list