簡體   English   中英

從應用程序調用時,Gnuplot崩潰

[英]Gnuplot crashes when called from application

我想使用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
};

沒有到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

以下代碼(在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服務器來與之交談。

因此,您應該詳細解釋如何啟動應用程序。 我想它恰好是因為Eclipse運行時只是因為Eclipse運行了一些X11服務器,而沒有Eclipse,你碰巧沒有任何X11服務器可用。 (我無法解釋為什么,這很大程度上取決於你啟動程序的方式。如果你正在使用ssh請不要忘記ssh -X並適當配置你的ssh )。

事實上,我的sleep呼叫是無用的。 但測試DISPLAY的存在至關重要。

它實際上是gnuplot一個錯誤,如果沒有DISPLAY ,它會更好地失敗; 我在他們的bug追蹤器上添加了一張票。 您可以使用未unset DISPLAY; echo 'plot sin(x); exit' | gnuplot -persist重現該錯誤unset DISPLAY; echo 'plot sin(x); exit' | gnuplot -persist unset DISPLAY; echo 'plot sin(x); exit' | gnuplot -persist

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM