3

我目前使用 C++ 使用 boost::graph 进行一些与图相关的计算。boost::graph 可以将其图形输出为点文件,我使用 std::stringstream 来捕获输出点文件。因此点文件的内容驻留在内存中。

我想使用点文件来可视化图形(尽可能快)。因此,我想生成点文件,生成 svg 文件并将其打印到某个画布上。我想避免为此使用临时文件,因为图形应该很小并且内存仍然可用。

然而,graphviz libgraph 只有这个功能extern Agraph_t *agread(FILE *);,我能想象到使这个工作的唯一方法是在文件句柄中破解,struct __FILE这实际上是不可移植的。

您如何让库将您的内存内容作为 Unix/linux 中的文件读取?

我刚刚发现 GraphViz 的 libcgraph 允许在此处输入重载版本,但到目前为止,文档并没有将我指向一些有用的地方。

4

4 回答 4

4

好吧,这可以说是 API 中的一个错误,但这里有一个想法。这是假设该agread()函数会将文件作为二进制数据读取。

请注意,我不熟悉您正在使用的 API,但我希望这无论如何都会有用。

  1. 使用 .将文件映射到内存中mmap()
  2. 使用该内存区域来构建图形。
  3. 当需要调用时agread(),将该文件描述符打开到FILE *结构中(fopen()或者fdopen()如果您没有关闭描述符)。
  4. 传递FILE *结构。

编辑:或者,忽略我的回答并使用fmemopen()电话。这可能正是您所需要的。不过,我不想删除我的答案,以防有人目前正​​在写回复:-)。

于 2011-10-07T15:37:38.270 回答
3

您可以创建一个管道pipe(),将数据写入输入端并使用fdopen()将输出文件描述符转换为适合传递到的文件句柄agread()

但是,这仅在您确定数据小于PIPE_BUFbytes时才有效;否则写入可能会永远阻塞,因为另一端没有读取任何内容。

一般来说,使用临时文件更容易也更可靠。只需用于tmpfile()获取文件句柄,将数据写入其中,倒带并将其传递给agread()

fh = tmpfile();
fputs( data, fh );
rewind( fh );
graph = agread( fh );
fclose( fh );

(当然,您应该检查错误,为了简洁起见,我没有这样做。)

于 2011-10-07T15:30:40.957 回答
1

如果您愿意使用 GNU libc 扩展,您可以将 C 字符串打开为FILE*; 该文档位于http://www.gnu.org/s/libc/manual/html_node/String-Streams.html

于 2011-10-12T22:41:07.940 回答
0

在 Windows 上,您可以使用 fopen 打开命名管道。

FILE* f = fopen("\\\\.\\Pipe\\<pipe name>", "rb");

所以你可以在一个单独的线程中创建一个管道,你可以在其中推送数据,agread 将从它读取而不需要临时文件。

于 2011-10-07T15:45:05.950 回答