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
};

4

Решение

Выполнение без ссылки на X-сервер вызовет эту проблему. Обычно ssh не дает вам ссылку на X-сервер (но может быть настроен или переключен для этого). Я обнаружил, что могу продублировать ошибку, процитированную «ssh localhost» и введя gnuplot и команду заговора, он предположит, что wxt — это тип терминала, и выдаст ошибку инициализации ошибки wxWidgets и ошибки сегмента.

Я считаю, что это будет работать для меня, если я сделаю это первым.

Предупреждение: первая команда «xhost +» опасна, она отключает безопасность X и позволяет подключаться к чему угодно, где угодно в Интернете, к вашему экрану, клавиатуре или мыши. Это может стать меньшей проблемой, если компьютер находится за маршрутизатором трансляции сетевых адресов, например, используемым в домашней сети.

Из оболочки:

xhost +
export DISPLAY=:0.0

Запустите gnuplot программно, затем отправьте команды gnuplot как обычно.
Должно сработать. Работает у меня на данный момент в логине ssh. Если этого не произойдет, проверьте env, который вы используете для запуска нового процесса, и вставьте туда явно «DISPLAY =: 0.0». Это значит подключиться к локальному дисплею. Имя хоста может быть добавлено до:

Под Linux gnuplot обычно ищет X-сервер. Возможно, не найти его.

Возможно, если целью является сохранение ваших графиков в файлах, то добавьте:

set terminal png
set output 'graph.png'

перед вашими командами gnuplot перед командой plot. Это должно работать даже на безголовых серверах.

Если вы хотите контролировать имя выходного файла, просто отправьте другое имя вместо graph.png

2

Другие решения

Следующий код (на 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;
}

(работает на Debian / Sid x86-64 с пакетом обновления 0 для gnuplot 4.6)

я думаю что sleepпрактически полезно gnuplot получить достаточно времени для работы. И не забудьте fflush после каждой команды.

Приложения:

Вы должны иметь DISPLAY, Если вы получили no display сообщение об ошибке означает, что вы запускаете программу в неправильной среде. Никакие уловки программирования не могут помочь в этом случае, так как gnuplot нужно немного X11 сервер поговорить с

Таким образом, вы должны объяснить гораздо больше, как вы запускаете приложение. Я предполагаю, что это работает из Eclipse просто потому, что Eclipse работает с некоторым сервером X11, в то время как без Eclipse у вас не будет ни одного сервера X11. (Я не могу объяснить, почему, это так сильно зависит от того, как вы запустите программу. ssh не забудь ssh -X и настройте свой SSH соответственно).

На самом деле мои звонки sleep бесполезны. Но тестирование существования DISPLAY необходимо.

Это на самом деле какая-то ошибка в gnuplot который должен потерпеть неудачу более красиво без DISPLAY; Я добавил билет на их баг-трекер. Вы можете воспроизвести ошибку с unset DISPLAY; echo 'plot sin(x); exit' | gnuplot -persist

1

По вопросам рекламы [email protected]