Не удается запустить команду оболочки в поддельном терминале VTE GTK4

Я сделал небольшой пример кода в gtk4 + vte для запуска поддельного терминала с кнопкой внизу для запуска простой команды при нажатии кнопки.

main.c

#include <gtk/gtk.h>
#include <vte/vte.h>
#define WINDOW_HEIGHT 400
#define WINDOW_WIDTH 600
GtkApplication *app;
GtkWidget *window, *terminal, *grid, *scrollview1,*button;
int status;

void run_button(void){
    char **argv_test[2] = {
        "echo\0",
        "Hello!!\0"
    };
    // can't run this command in fake terminal!
    vte_terminal_spawn_async(VTE_TERMINAL(terminal),VTE_PTY_NO_HELPER,NULL,argv_test,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL,NULL,2000,NULL,NULL,NULL);
}

void window_renderer(GtkApplication *app, gpointer user_data) {
    window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(window),"My terminal");
    gtk_window_set_default_size (GTK_WINDOW(window), WINDOW_WIDTH, WINDOW_HEIGHT);
    grid = gtk_grid_new();
    gtk_window_set_child(GTK_WINDOW(window), grid);
    gtk_widget_set_vexpand(grid,TRUE);
    gtk_widget_set_hexpand(grid,TRUE);
    scrollview1 = gtk_scrolled_window_new();
    gtk_grid_attach(GTK_GRID(grid), scrollview1, 0, 0, 1, 1);
    gtk_widget_set_size_request(GTK_WIDGET(scrollview1),WINDOW_WIDTH,WINDOW_HEIGHT);
    button = gtk_button_new_with_label("Run!");
    gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 1, 1);
    g_signal_connect(button,"clicked", G_CALLBACK(run_button), NULL);
    terminal = vte_terminal_new();
    gtk_window_set_child(GTK_WINDOW(scrollview1), terminal);
    gtk_widget_show(window);
}

int main(int argc, char **argv)
{
    app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app,"activate", G_CALLBACK(window_renderer), NULL);
    status = g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);
    return status;
}

Makefile

CFLAGS += -Wall
CFLAGS += `pkg-config --cflags gtk4 vte-2.91-gtk4`
LIBS += `pkg-config --libs gtk4 vte-2.91-gtk4`

.PHONY: all clean

all: main

main:main.c
    gcc $(CFLAGS) main.c -o main $(LIBS)

clean:
    rm main

Я скомпилировал VTE (для gtk4) и пакет разработчика gtk4, сборка приложения gtk4 не проблема!

При запуске встроенного бинарника программа вылетает, когда я нажимаю кнопку с ошибкой сегментации, вероятно, из-за неправильно инициализированного указателя (согласно учебные пособия).

Может ли кто-нибудь помочь мне узнать, что я пропустил?

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
0
27
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я протестировал ваш код и полагаю, что обнаружил основную проблему с вашей командой терминала, а также некоторые предупреждения, которые отображались при тестировании. Во-первых, из обзора другого примера кода с использованием функции «vte_terminal_spawn_async» набор символов включал в себя конечный элемент массива «NULL». Поэтому вместо следующего фрагмента кода.

char **argv_test[2] = {
    "echo\0",
    "Hello!!\0"
};

Вам нужно будет добавить третий элемент массива, как в следующем исправленном фрагменте кода.

char *argv_test[3] = {
    "echo\0", "Hello!!\0", NULL
};

Если вы заметили еще одну незначительную поправку к приведенному выше фрагменту кода, я изменил определение массива символов с «char ** argv_test[3]» на «char *argv_test[3]». Компилятор выводил предупреждение о несовместимых ссылках на указатели. Кроме того, когда я тестировал этот код, я получал предупреждение и не мог просматривать терминал, когда была нажата кнопка «Выполнить».

Gtk-CRITICAL **: 14:49:46.383: gtk_window_set_child: assertion 'GTK_IS_WINDOW (window)' failed

Из предыдущего устранения неполадок с другим пользователем мы определили, что дочерняя настройка для прокручиваемого окна должна использовать функцию ссылки на дочерний элемент прокручиваемого окна вместе с макросом прокручиваемого окна. Поэтому я изменил дочернее назначение прокручиваемого окна следующим образом.

gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrollview1), terminal);

Внесение этих небольших изменений привело к отображению терминала с вашей командой «echo Hello» (я дважды нажал кнопку во время тестирования).

Sample Terminal

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

С уважением.

Другие вопросы по теме