FaqAgreadCrash

This usually happens when the Graphviz library is built using one version of the stdio library, and the user's program is compiled using another. If the FILE structure of stdio is different, the call to agread() will cause a crash. This is mainly a problem on Windows where we just provide a binary release built with one version of Visual Studio and stdio changes depending on the version of Visual Studio. It can also occur if the user tries to use cygwin or something similar which may also use an incompatible stdio.

The simplest solution is to read in the entire graph into memory, and pass a pointer to that memory to agmemread().

If that is not possible (e.g., the file is too large), you need to tell agread() to use a reader compatible with the stream you give it. By default, agread assumes you are passing it a FILE* generated by the version of stdio that was used to compile Graphviz, and uses that version of fgets to read the stream. To pass in your own reader, use the third argument:

Agdisc_t mydisc;
Agodisc_t myiodisc;

mydisc.mem = NULL;  // use system default
mydisc.id = NULL;   // use system default
mydisc.io = &myiodisc;
myiodisc.afread = reader; 
myiodisc.putstr = NULL;  // only need to set if calling gvRender()
myiodisc.flush = NULL;   // only need to set if calling gvRender()

The reader function has type

  int (*reader) (void *chan, char *buf, int bufsize);

and should act like the read() system call. That is, it reads from
the stream chan, storing the bytes in buf, whose size is bufsize,
and returns the number of bytes it read. 

For Unix-like stdio, one might use

static int reader(void *chan, char *buf, int bufsize)
{
    return fread(buf, 1, bufsize, (FILE*)chan); 
}

Then, to read the graph, use:

FILE* fp = fopen ("mygraph.gv","r");
Agraph_t* g = agread (fp, &mydisc);

Recent comments