Вызов библиотечной функции с изюминкой — изменение ее поведения

Я пытаюсь встроить октавную библиотеку в большую программу. Требуется, чтобы я мог по желанию запускать и останавливать интерпретатор октав из этой более крупной программы. Однако единственная функция, которая корректно останавливает интерпретатор октавы, также вызывает функцию exit (), которая также убивает большую программу. Функция библиотеки октав — clean_up_and_exit ().

В идеале я хотел бы вызвать только часть очистки (do_octave_atexit) и пропустить вызов для выхода.

Я попробовал следующее:

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

2) Я попытался подключиться к вызову exit и заменить его функцией, которая не завершается, через ld_preload. Это все испортило, так как все другие вызовы на выход были подключены.

3) Я пытался определить, когда выход вызывается октавой, только чтобы предотвратить это только тогда, обнаруживая вызывающую функцию с вызовом backtrace. Это по какой-то причине не показывало то, что я ожидал бы быть истинной иерархией вызовов. По какой-то причине он только показал основную функцию, а не содержимое иерархии вызовов через октавную библиотеку. Таким образом, он не смог обнаружить звонок из октавы.

Код, который я использую для вызова октавных функций, выглядит следующим образом:

//
// Octave Setup Functions
//
extern "C" void oct_init (const char * path) {
string_vector argv (2);
argv(0) = "embedded";
argv(1) = "-q";

octave_main (2, argv.c_str_vec (), 1);
if(strlen(path) > 1) {
oct_addpath(path);
}
}

extern "C" void oct_exit (void) {
printf("Exiting!");
clean_up_and_exit (1,1);
}

Ключевой функцией здесь является clean_up_and_exit, которая реализована в источнике октавы как:

void clean_up_and_exit (int retval, bool safe_to_return)
{
do_octave_atexit ();

if (octave_link::exit (retval))
{
if (safe_to_return)
return;
else
{
gnulib::sleep (86400);
}
}
else
{
if (octave_exit)
(*octave_exit) (retval);
}
}

Таким образом, приведенный выше код вызывает функцию, которую я хочу (do_octave_atexit), но затем переходит к вызову * octave_exit — который является указателем на функцию exit ().

В идеале я хочу либо a) запретить этот вызов для exit (), либо b) перехватить вызов, когда он поступает только из октавы, и запретить его, а также разрешить, когда он поступает из других источников. Я не смог сделать а) или б) до сих пор!

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

Это должно было работать только в среде linux / gcc.

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

1

Решение

Вам придется раскошелиться и запустить Octave в отдельном процессе. Вот простой пример того, как это сделать:

#include <unistd.h>
#include <iostream>

#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h>

int
main_octave (void)
{
string_vector argv (2);
argv(0) = "embedded";
argv(1) = "-q";

octave_main (2, argv.c_str_vec (), 1);

octave_value_list out = feval ("pi", octave_value_list (0), 1);
if (! error_state && out.length () > 0)
std::cout << "pi is " << out(0).double_value () << std::endl;
else
std::cout << "invalid\n";

clean_up_and_exit (0);
}

int
main (void)
{
pid_t pid = fork();
if (pid == 0)
main_octave ();
else if (pid > 0)
{
std::cout << "Parent process going for a nap" << std::endl;
sleep (5);
}
else
{
std::cout << "Unable to fork()" << std::endl;
return 1;
}
std::cout << "Leaving standalone application" << std::endl;
return 0;
}

Который в моей системе возвращает:

$ mkoctfile --link-stand-alone embedded.cc -o embedded
$ ./embedded
Parent process going for a nap
pi is 3.14159
Leaving standalone application

Таким образом, вы можете продолжить работу приложения после выхода из процесса Octave. Конечно, если вы хотите запускать и останавливать Octave несколько раз, то вам придется разветвляться несколько раз. Кроме того, я бы порекомендовал вам задавать такие вопросы в списке рассылки справки Octave, там вы, скорее всего, быстрее получите полезные ответы.

1

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector