调用带有扭曲的库函数-修改其某些行为

Calling a library function with a twist - modifying some of its behaviour

本文关键字:修改 库函数 调用      更新时间:2023-10-16

我正试图将八度音阶库嵌入到一个更大的程序中。要求我可以从这个更大的程序中随意启动和停止八度音阶解释器。然而,唯一能干净地停止倍频程解释器的函数也调用exit(),这也会杀死更大的程序。倍频程库函数是clean_up_and_exit()。

理想情况下,我只想调用cleanup部分(do_octave_atexit),然后跳过调用退出。

我尝试了以下方法:

1) 调用do_octave_atexit,但是该符号不会在倍频程库中导出。我试着访问它,但没有成功。

2) 我尝试挂接调用以退出,并通过ld_proad将其替换为不退出的函数。这把一切都搞砸了,因为所有其他的退出电话都被钩住了。

3) 我试图检测出口何时被八度音阶调用,只是为了防止它,通过调用回溯检测调用函数。出于某种原因,这并没有显示出我所期望的真正的调用层次结构。出于某种原因,它只显示了主要功能,而没有通过倍频程库显示调用层次结构的内容。所以in无法检测到来自八度音阶的呼叫。

我用来调用倍频程函数的代码看起来像:

//
// 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环境中工作即可。

对于这个非常棘手的问题,我们非常感谢所有的建议。

您必须在一个单独的进程上分叉并运行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 << "invalidn";
  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帮助邮件列表中询问这样的问题,你更有可能更快地得到有用的答案。