从应用程序调用时,Gnuplot崩溃

时间:2013-04-21 09:41:29

标签: c++ linux gnuplot

我想使用gnuplot在控制台应用程序(C ++,Eclipse CDT,Linux)中绘制我的结果。我创建了一个简单的类来简化操作(参见下面的代码)。我试着在我的主要情节中绘制测试图:

int main() {

    Gnuplot plot;

    plot("plot sin(x)") ;

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

    return 0;
}

我的问题是,如果我正常启动我的应用程序,我会收到一条运行时错误消息“无法初始化wxWidgets”。执行线图(“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
};

2 个答案:

答案 0 :(得分:2)

执行没有指向X服务器的链接会导致此问题。通常情况下,ssh不会为您提供指向X服务器的链接(但可以配置或切换为执行此操作)。我发现我可以复制“ssh localhost”引用的错误并输入gnuplot和一个绘图命令,它会假设wxt是终端类型并且无法初始化wxWidgets错误和segfault。

但是,如果我先这样做,我发现它对我有用。

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

来自shell:

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

答案 1 :(得分: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 patchlevel 0处理Debian / Sid x86-64)

我想sleep - 让gnuplot有足够的时间来工作是非常有用的。并且在每个命令之后不要忘记fflush

附加物:

你应该有DISPLAY。如果您收到no display错误消息,则表示您在错误的环境中启动程序。在这种情况下,没有编程技巧可以提供帮助,因为gnuplot需要一些X11 server来与之交谈。

因此,您应该详细解释如何启动应用程序。我想它恰好是因为Eclipse运行时只是因为Eclipse运行了一些X11服务器,而没有Eclipse,你碰巧没有任何X11服务器可用。 (我无法解释原因,这很大程度上取决于您启动程序的方式。如果您ssh不要忘记ssh -X并正确配置 ssh 。< / p>

事实上,我对sleep的调用毫无用处。但是测试DISPLAY的存在是至关重要的。

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

重现该错误