Search code examples
c++c++11qt-creatorgraphvizdynamic-library

Graphviz as library in windows


I am contacting you regarding Graphviz libraries. I have a bug that I observed when using graphviz as a library within c++ code and qt creator on windows.

Based on the example from the Documentation, I used the following function to convert a dot file in png file:

bool saveImageGV(){       

    GVC_t *gvc= gvContext();

    gvAddLibrary(gvc, &gvplugin_dot_layout_LTX_library);

    gvAddLibrary(gvc, &gvplugin_core_LTX_library);

    gvAddLibrary(gvc, &gvplugin_gd_LTX_library);

    FILE *fp = fopen((pathTmp + ".dot").c_str(), "r");

    Agraph_t *g = agread(fp,0);

    gvLayout(gvc, g, "dot");

    FILE *fp2 = fopen((pathTmp  + ".png").c_str(), "w");

    gvRender(gvc, g, "png", fp2);

    gvFreeLayout(gvc, g);

    agclose(g); fclose(fp); fclose(fp2);

    return (gvFreeContext(gvc));

}

It appears that on linux, this function works very well with graphviz 2.30 and I succeed to convert my dot file into a png file. However, when I use the windows libraries, I got a segmentation fault with the same function. My investigations let me think the problems could come from the .dll libraries as, on linux, it worked with the 2.30 version but not with the 2.38 version of the libraries. With windows, 2.30 and 2.38 lead to the same error of segmentation fault.

Is it a well known bug and it exists another way to convert a dot file into png file on windows? I link the libraries from the "Graphviz2.38\lib\release\lib" folder and take the dlls from "Graphviz2.38\lib\release\dll" folder.

I thank you in advance for your response and if you need more information.


Solution

  • graphviz FAQ

    maybe it's because of a wrong version of stdio

    i had segmentation fault happened in visual studio and here is the solution (using /std:c++latest so the syntax does not conform to the standard, the code is only for understanding)

    Agiodisc_t my_iodisc = {
        .afread = [](void* chan, char* buf, int bufsize)->int
        {
            return fread(buf, 1, bufsize, (FILE*)chan);
        },
        .putstr = [](void* chan,const char* buf)->int
        {
            return fwrite(buf, 1, strlen(buf), (FILE*)chan);
        },
        .flush = [](void* chan)->int
        {
            return fflush((FILE*)chan);
        }
    };
    Agdisc_t my_disc = {
        .mem = NULL, // use system default
        .id = NULL, // use system default
        .io = &my_iodisc
    };
    FILE* p_file = fopen("1.gv", "r");
    Agraph_t* g = agread(p_file, &my_disc);
    fclose(p_file);