[英]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.