我正在尝试将八度音程库嵌入到更大的程序中。我需要从这个更大的程序中随意启动和停止八度音译器。但是,唯一能够干净地停止八度音译器的函数也会调用exit(),这也会杀死更大的程序。八度音程库函数是clean_up_and_exit()。
理想情况下,我只想调用清理部分(do_octave_atexit),并跳过调用退出。
我尝试了以下内容:
1)调用do_octave_atexit,但符号不会在八度音阶库中导出。无论如何我试图访问它但无济于事。
2)我试图通过ld_preload挂钩调用exit,并用一个不退出的函数替换它。这一切搞砸了所有其他的退出调用也被搞砸了。
3)我试图通过调用回溯检测调用函数来检测何时仅通过八度音调调用exit以防止它被调用。由于某种原因,这并没有表明我期望成为真正的呼叫层次结构。由于某种原因,它只显示了main函数,并且没有通过octave库显示调用层次结构的内容。因此无法检测到来自八度的呼叫。
我用来调用八度音阶函数的代码如下:
//
// 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)仅在来自八度音阶时捕获调用并阻止它,并在来自其他来源时允许它。到目前为止,我还没能做到a)或b)!
所以在这一点上我没有想法。我可以重新编译八度音程,但是这个解决方案应该适用于八度音调安装。
这只需要在linux / gcc环境下工作。
对这个非常棘手的问题的任何和所有建议都非常感激。
答案 0 :(得分: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帮助邮件列表上询问这些事情,你更有可能在那里更快地得到有用的答案。