A.1.8 从 Oct-File 中调用 Octave 函数

经常需要从 oct-file 内部调用另一个 Octave 函数,在 Octave 本身中有很多这样的例子。例如,quad 函数就是一个 oct-file,它通过对用户提供的函数进行数值积分来计算定积分。

函数可以通过多种方式作为输入给出。它可以通过以下方式之一传递:

  1. 函数句柄(Function Handle)
  2. 匿名函数句柄(Anonymous Function Handle)
  3. 字符串(String)

下面的代码演示了将所有四种方式将函数传递给 oct-file。

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

DEFMETHOD_DLD (funcdemo, interp, args, nargout, "Function Demo")
{
  int nargin = args.length ();

  if (nargin < 2)
    print_usage ();

  octave_value_list newargs;

  for (octave_idx_type i = nargin - 1; i > 0; i--)
    newargs(i-1) = args(i);

  octave_value_list retval;

  if (args(0).is_function_handle () || args(0).is_inline_function ()
      || args(0).is_string ())
    retval = interp.feval (args(0), newargs, nargout);
  else
    error ("funcdemo: INPUT must be string, inline, or function handle");

  return retval;
}

演示代码的第一个输入是用户提供的函数,其余参数都将传递给该函数。

funcdemo (@sin, 1)
⇒   0.84147
funcdemo (@(x) sin (x), 1)
⇒   0.84147
funcdemo ("sin", 1)
⇒   0.84147
funcdemo (@atan2, 1, 1)
⇒   0.78540

当用户函数作为字符串传递时,函数的处理方式有所不同。在某些情况下,需要将用户提供的函数作为 octave_function 对象来处理。在这种情况下,字符串参数可用于创建一个临时函数,如下所示。

std::octave fcn_name = unique_symbol_name ("__fcn__");
std::string fcode = "function y = ";
fcode.append (fcn_name);
fcode.append ("(x) y = ");
fcn = extract_function (args(0), "funcdemo", fcn_name,
                        fcode, "; endfunction");
...
if (fcn_name.length ())
  clear_function (fcn_name);

在这种情况下,有两件重要的事情需要了解。首先,用户函数的输入参数数量是固定的,在上面的例子中是一个单一参数。其次,为了避免将临时函数留在 Octave 的符号表中,在使用后应将其清除。此外,按照惯例,所有内部函数名称都以字符序列 ‘__’ 开头和结尾。


版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-2