Thread: Oddities reading binary data

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    4

    Oddities reading binary data

    I could use some enlightment on binary file i/o, especially in conjunction with writing libraries. I'm trying to play with the JPL ephemerides routines available at http://ephemeris.com/software.html. I can compile the code and run it with no problem. All the tests run successfully.

    The problem comes in when I try to move the gnulliver.c, ephcom.c, and ephcom.h files off into a compiled library and then use them. I'm using the testeph program in this case but am seeing the problem no matter how I access the library routines.

    The problem appears to arise in ephcom.c, line 970. When being run in a library the feof(infp) evaluates to true early. It varies depending on the particular call but it is dies when the loop index is somewhere in the 16 to 38 range. When this code is run when compiled directly with the test program, the loop runs through fully to i = 1018.

    There are no code changes at all. The only difference is that in one I'm compiling the four files:
    ephcom.c
    ephcom.h
    gnulliver.c
    testeph.c
    Together to get an executeable. That way works. The other way, I compile the first three files together into a library and then compile testeph.c and link it with that compiled library. I've tried using netbeans 6.5/gcc and MS Visual Studio Express 2008 and see the same thing. I've tried making the library both a statically linked one or a dynamically linked one.

    I know that I'm not real clear on the details of passing FILE *pointers to libraries and suspect that it may be related to that. The part that perplexes me the most is that the reading from the file works for the first few values per block and then suddenly breaks down.

    The function where things break down is:
    Code:
    int ephcom_readbinary_block(
       FILE *infp,                    /* File pointer for direct access file */
       struct ephcom_Header *header,  /* header struct, already filled in    */
       int blocknum,                  /* Data block number, starting with 0  */
       double *datablock              /* returned coefficient data block     */
       ) {
    
    int i;
    long filebyte;
    double ephcom_indouble(FILE *);
    int fseek(FILE *, long, int);
    
    filebyte = (blocknum + 2) * header->ncoeff * 8; /* 8 bytes per coefficient */
    fseek(infp, filebyte, SEEK_SET);
    // printf("Blocknum: %d, Byte: %d\n", blocknum, filebyte);
    for (i=0; !feof(infp) && i<header->ncoeff; i++) {
       datablock[i] = ephcom_indouble(infp);
       }
    if (i < header->ncoeff && feof(infp)) i = -1; /* 0 --> EOF */
    return(i); /* Number of coefficients successfuly read (all or nohing). */
    }
    Any specific help or any general pointers to info about using FILE *pointers with libraries would probably be helpful.

    Thanks in advance.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    On windows, you will need to make sure that all the fopen calls for binary files are "rb" and "wb" as appropriate.

    If you examine your files using a hex editor, you should see that the code breaks when it reaches a char(26) in the file. This is an end of file marker when reading files in text mode.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    The good news is that ensuring that I did the fopen in "rb" rather than just "r" mode did make the code work in the library.

    The bad news is that I'm still somewhat confused. Why did opening it with "r" work just fine when everything was compiled together but only break when compiling into a library and then linking?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I thought this was the usual Unix ported to windows problem.

    Are you saying that just creating a library without changing OS/Compiler was the cause of the breakage?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    Yes, exactly. There are four source files, one containing the main and the others containing supporting functions. When I compile them all together into an executable, then it all works just fine with the code as is. When I compile the three supporting files into a library, then compile the fourth (with the "main") seperately and simply link to the precompiled library, that's when things broke.

    The fopen gets called in "main" but all the fgetc/feof calls are in the supporting functions (in the library). Now, when I made sure to switch to "rb" in the fopen, the library version works just fine.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Yeah, that's pretty weird.

    I can't think of anything to explain why your first case would work.

    The code is pretty dubious though. It mixes fgets(), fgetc() and fread() all on the same file. Such files are simply horrible for porting to another environment. Hence the "rb" suggestion for reading the Unix generated files on your windows box.

    Did you use a visual studio project to compile the 4 files, and was that project provided to you?
    Did you create another project(s) for the 3-in-a-lib + one source file combination?
    Careful examination of compiler options, and build/linker logs might throw up some subtle differences.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Feb 2009
    Posts
    4
    No projects were supplised, just the source files.

    I tried with projects both in Visual Studio and NetBeans/GCC. I did create the projects myself from scratch. I've been looking through the options and haven't found any differences yet, but will keep looking into it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with Reading and writing binary data
    By Yasir_Malik in forum C Programming
    Replies: 3
    Last Post: 12-12-2004, 09:24 AM
  2. Reading a line of data...
    By RedZippo in forum C++ Programming
    Replies: 10
    Last Post: 04-04-2004, 02:14 AM
  3. Templated Binary Tree... dear god...
    By Nakeerb in forum C++ Programming
    Replies: 15
    Last Post: 01-17-2003, 02:24 AM
  4. Reading Binary Data
    By pinkcheese in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 09-30-2002, 05:14 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM

Tags for this Thread