Unable to use dot layout (graphviz as a library)

旧时模样 提交于 2019-12-19 08:58:29

问题


I use graphviz (v2.28.0) as a library in a C++ application and I would like to render graphs using the dot layout. Everything works fine until I call the gvLayout(_context, _graph, "dot"); function which outputs the following error :

 Error: Layout type: "dot" not recognized. Use one of:

I use the following library flags when linking :

-lgvc -lgraph -lpathplan -lcdt -lgvplugin_dot_layout

Calling dot from the Unix command line works as expected. What am I doing wrong ?


回答1:


You probably either already fixed this or gave up, but I ended up here so I'm sure someone else will...

Plugins need to be loaded explicitly. I'm not sure whether this is related to static linking or needs to be done whenever graphviz is used as a library.

This fixed dot for me:

extern gvplugin_library_t gvplugin_dot_layout_LTX_library;
gvAddLibrary(gvc, &gvplugin_dot_layout_LTX_library);



回答2:


I got this error when I added the "-O2" optimization flag to gcc when I compiled graphviz on macosx. When I removed that flag, the error went away.




回答3:


Do you use graphviz with dynamic library loading? In a static environment the following lines may help:

#include "gvplugin.h"

extern gvplugin_library_t gvplugin_dot_layout_LTX_library;
extern gvplugin_library_t gvplugin_neato_layout_LTX_library;
extern gvplugin_library_t gvplugin_core_LTX_library;
extern gvplugin_library_t gvplugin_quartz_LTX_library;
extern gvplugin_library_t gvplugin_visio_LTX_library;

lt_symlist_t lt_preloaded_symbols[] =
{
    { "gvplugin_dot_layout_LTX_library", &gvplugin_dot_layout_LTX_library},
    { "gvplugin_neato_layout_LTX_library", &gvplugin_neato_layout_LTX_library},
    { "gvplugin_core_LTX_library", &gvplugin_core_LTX_library},
    { "gvplugin_quartz_LTX_library", &gvplugin_quartz_LTX_library},
    { "gvplugin_visio_LTX_library", &gvplugin_visio_LTX_library},
    { 0, 0}
};



回答4:


According to a reply by Emden R. Gansner on the 'graphviz-interest' mailing list, this error message indicates that the software was unable to find the graphviz config file.

The graphviz config file (config6) is used by the gvc library to load the various libgvplugin_... libraries on demand.

Gansner also mentions that graphviz supports a GVBINDIR environment variable which, if defined, is used to specify the directory containing the graphviz config file. This is also discussed at How to configure & package Graphviz for Mac App Store?.

In my case (where I'm trying to include the graphviz libraries in an macOS/Objective-C framework), a framework subdirectory (called "Libraries") contains the config6 file plus these libgvplugin_... libraries (next to the regular graphviz libraries):

Libraries:
    config6
    libgvplugin_core.6.dylib
    libgvplugin_dot_layout.6.dylib
    libgvplugin_gd.6.dylib
    libgvplugin_neato_layout.6.dylib
    libgvplugin_quartz.6.dylib

From within one of the framework's classes, one could then set the GVBINDIR environment variable like this:

NSBundle *containingBundle = [NSBundle bundleForClass:[self class]];
NSURL *librariesDirURL = [[containingBundle bundleURL] URLByAppendingPathComponent:@"Versions/A/Libraries" isDirectory:YES];
if (librariesDirURL) {
    setenv("GVBINDIR", (char*)[[librariesDirURL path] UTF8String], 1);
}

Setting the GVBINDIR environment variable is the only solution that worked for me.

I've also tried the solutions mentioned by others above including loading the default graphviz plugins explicitly. E.g., with _graphContext being defined as static GVC_t *_graphContext, this code:

extern gvplugin_library_t gvplugin_dot_layout_LTX_library;
extern gvplugin_library_t gvplugin_neato_layout_LTX_library;
extern gvplugin_library_t gvplugin_core_LTX_library;
extern gvplugin_library_t gvplugin_quartz_LTX_library;

lt_symlist_t lt_preloaded_symbols[] =
{
    { "gvplugin_dot_layout_LTX_library", &gvplugin_dot_layout_LTX_library},
    { "gvplugin_neato_layout_LTX_library", &gvplugin_neato_layout_LTX_library},
    { "gvplugin_core_LTX_library", &gvplugin_core_LTX_library},
    { "gvplugin_quartz_LTX_library", &gvplugin_quartz_LTX_library},
    { 0, 0}
};

_graphContext = gvContextPlugins(lt_preloaded_symbols, 1);

actually worked for me. I.e., this caused the graphviz plugins to load and the above mentioned error message ('Error: Layout type: "dot" not recognized. Use one of:') vanished. However, any subsequent call to gvLayout() then caused a graphviz crash (EXC_BAD_ACCESS) for me.

So for now I'm taking the environment variable approach.



来源:https://stackoverflow.com/questions/9602127/unable-to-use-dot-layout-graphviz-as-a-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!