tags:

views:

226

answers:

2

Once again, here I am writing C without really knowing what I'm doing...

I've slapped together a simple function that I can call from a C# program that takes a DOT string, an output format, and a file name and renders a graph using Graphviz.

#include "types.h"
#include "graph.h"
#include "gvc.h"

#define FUNC_EXPORT __declspec(dllexport)

// Return codes
#define GVUTIL_SUCCESS          0
#define GVUTIL_ERROR_GVC        1
#define GVUTIL_ERROR_DOT        2
#define GVUTIL_ERROR_LAYOUT     3
#define GVUTIL_ERROR_RENDER     4

FUNC_EXPORT int RenderDot(char * dotData, const char * format,
        const char * fileName) {
    Agraph_t * g;    // The graph
    GVC_t * gvc;     // The Graphviz context
    int result;      // Result of layout and render operations

    // Create a new graphviz context
    gvc = gvContext();
    if (!gvc) return GVUTIL_ERROR_GVC;

    // Read the DOT data into the graph
    g = agmemread(dotData);
    if (!g) return GVUTIL_ERROR_DOT;

    // Layout the graph
    result = gvLayout(gvc, g, "dot");
    if (result) return GVUTIL_ERROR_LAYOUT;

    // Render the graph
    result = gvRenderFilename(gvc, g, format, fileName);
    if (result) return GVUTIL_ERROR_RENDER;

    // Free the layout
    gvFreeLayout(gvc, g);

    // Close the graph
    agclose(g);

    // Free the graphviz context
    gvFreeContext(gvc);

    return GVUTIL_SUCCESS;
}

It compiles fine, but when I call it, I get GVUTIL_ERROR_LAYOUT. At first, I thought it might have been how I was declaring my P/Invoke signature, so I tested it from a C program instead, but it still failed in the same way.

RenderDot("digraph graphname { a -> b -> c; }", "png", "C:\testgraph.png");

Did I miss something?

EDIT

If there's a chance it has to do with how I'm compiling the code, here's the command I'm using:

cl gvutil.c /I "C:\Program Files (x86)\Graphviz2.26\include\graphviz"
    /LD /link /LIBPATH:"C:\Program Files (x86)\Graphviz2.26\lib\release"
    gvc.lib graph.lib cdt.lib pathplan.lib

I've been following this tutorial that explains how to use Graphviz as a library, so I linked to the .lib files that it listed.

A: 

Graphviz loads layout and rendering plugins dynamically based on information in a configuration file, which I had not copied to my application's directory.

David Brown
A: 

Hi,

I have a question related to this.

I am trying to write a C file making use of the Graphviz library in Windows.

And it breaks down at the same point giving a windows error of "The memory could not be written".

when i put printf satatemens in the file, i see it breaks at the same point as u say.

Can i know about this configuration file and where is it present in the Graphviz installation and where must it be put into?

Namratha
The configuration file is in the Graphviz installation directory, alongside the DLL files. Mine was called "config6", but I believe the number changes. If you don't have a configuration file, you can generate one with the command "dot -c". Just copy that file to your application's directory.
David Brown