4

我想使用 gnuplot 在控制台应用程序(C++、Eclipse CDT、Linux)中绘制我的结果。我创建了一个简单的类来使事情变得更容易(见下面的代码)。我尝试在我的主要中绘制一个测试图:

int main() {

    Gnuplot plot;

    plot("plot sin(x)") ;

    cout<<"Press button:";
    cin.get();

    return 0;
}

我的问题是,如果我正常启动我的应用程序,我会收到一条运行时错误消息“无法初始化 wxWidgets。执行线 plot("plot sin(x)") 后出现分段错误(核心转储)'。但是,如果我在调试模式下单步执行这些行,则代码可以正常工作,并且我的绘图窗口按预期显示为正弦。欢迎任何帮助。

#ifndef GNUPLOT_H_
#define GNUPLOT_H_

#include <string>
using namespace std;

class Gnuplot {

    public:
        Gnuplot() ;
        ~Gnuplot();
        void operator ()(const string & command); // send any command to gnuplot

    protected:
        FILE *gnuplotpipe;
};
#endif

和来源:

#include "gnuplot.h"
#include <iostream>
#include <string>
#include "stdio.h"

Gnuplot::Gnuplot() {

    gnuplotpipe=popen("gnuplot -persist","w");
    if (!gnuplotpipe) {
    cerr<< ("Gnuplot not found !");
    }
}

Gnuplot::~Gnuplot() {

    fprintf(gnuplotpipe,"exit\n");
    pclose(gnuplotpipe);
}

void Gnuplot::operator()(const string & command) {

    fprintf(gnuplotpipe,"%s\n",command.c_str());
    fflush(gnuplotpipe);// flush is neccessary, nothing gets plotted else
};
4

2 回答 2

2

在没有到 X 服务器的链接的情况下执行将导致此问题。通常 ssh 不会为您提供到 X 服务器的链接(但可以配置或切换到这样做)。我发现我可以复制“ssh localhost”引用的错误并输入 gnuplot 和绘图命令,它将假定 wxt 是终端类型并给出失败的初始化 wxWidgets 错误和段错误。

不过,如果我先这样做,我发现它对我有用。

警告:第一个命令“xhost +”很危险,它会禁用 X 安全性并允许互联网上的任何地方连接到您的屏幕、键盘或鼠标。 如果机器位于网络地址转换路由器(例如家庭网络中使用的路由器)后面,这可能不是问题。

从外壳:

xhost +
export DISPLAY=:0.0

以编程方式启动 gnuplot,然后正常发送 gnuplot 命令。
应该管用。目前在 ssh 登录中为我工作。如果没有,请检查您用于启动新进程的环境,并将“DISPLAY=:0.0”明确放入其中。这意味着连接到本地显示器。主机名可以在 :

在 Linux 下,gnuplot 通常会寻找 X 服务器。它可能找不到它。

如果目标是将图形保存在文件中,则添加:

set terminal png
set output 'graph.png'

在“plot”命令之前添加到您的 gnuplot 命令。这甚至应该在无头服务器上工作。

如果您想控制输出文件名,只需发送其他名称而不是 graph.png

于 2013-04-21T10:50:31.660 回答
1

以下代码(在 C 中,而不是 C++ 中)对我来说很好(当从某个 X11 会话中的终端启动时,因此DISPLAY设置为:0.0):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char**argv)
{
  FILE *gp = NULL;
  if (!getenv("DISPLAY")) 
    {fprintf(stderr, "no display\n"); exit(EXIT_FAILURE);};
  gp = popen("gnuplot -persist", "w");
  if (!gp) {perror("gnuplot popen"); exit(EXIT_FAILURE);};
  //sleep (1);
  fprintf(gp, "plot sin(x)\n");
  fflush(gp);
  fprintf(gp, "exit\n");
  fflush(gp);
  //sleep (1);
  pclose (gp);
  return 0;
}     

(使用 gnuplot 4.6 补丁级别 0 在 Debian/Sid x86-64 上工作)

我想-ing 对于让有足够的时间工作sleep实际上很有用。gnuplot并且不要忘记fflush在每个命令之后。

附加物:

你应该有一个DISPLAY. 如果您收到no display错误消息,则表示您在错误的环境中启动程序。在这种情况下,任何编程技巧都无济于事,因为gnuplot需要一些X11 服务器与之通信。

所以你应该更多地解释你是如何开始你的应用程序的。我猜它恰好可以在 Eclipse 中工作,仅仅是因为 Eclipse 使用一些 X11 服务器运行,而没有 Eclipse,你碰巧没有任何可用的 X11 服务器。(我无法解释为什么,这在很大程度上取决于您启动程序的方式。如果使用ssh,请不要忘记ssh -X并适当地配置您的ssh)。

事实上,我的呼吁sleep是无用的。但是测试 a 的存在DISPLAY是必不可少的。

它实际上是一些错误,如果没有;gnuplot应该会更好地失败。DISPLAY我在他们的错误跟踪器上添加了一张票。您可以使用重现该错误unset DISPLAY; echo 'plot sin(x); exit' | gnuplot -persist

于 2013-04-21T10:33:26.473 回答