A.1.1 Oct-Files 入门

Oct-Files 是使用 Octave API 编译成动态可加载对象的 C++ 代码。它们的名称来源于包含该对象的文件,该文件扩展名为 .oct

寻找合适的 C++ 编译器、使用正确的编译选项、为头文件添加正确的包含路径等,是一项艰巨的任务。Octave 通过提供 mkoctfile 命令来自动化此过程,该命令用于构建 oct 文件。此命令可在 Octave 内部或 shell 命令行中使用。

 
mkoctfile [-options] file …
[output, status] = mkoctfile (…)

mkoctfile 函数用于编译用 C、C++ 或 Fortran 编写的源代码。根据与 mkoctfile 一起使用的选项,编译后的代码可以在 Octave 中调用,也可以用作独立应用程序。

mkoctfile 可以从 shell 提示符或 Octave 提示符调用。从 Octave 提示符调用时,实际上是将调用委托给 shell 提示符。任何输出都会存储在 output 变量中,退出状态存储在 status 变量中。如果在没有输出参数的情况下调用且编译失败,Octave 会报错。但是,如果程序员请求了 outputstatus 变量,则 Octave 仅会发出警告,由程序员负责验证命令是否成功执行。

mkoctfile 接受以下选项,除要编译的代码文件名外,所有选项都是可选的:

-I DIR

将包含目录 DIR 添加到编译命令中。

-D DEF

将定义 DEF 添加到编译器调用中。

-l LIB

将库 LIB 添加到链接命令中。

-L DIR

将库目录 DIR 添加到链接命令中。

-M
--depend

为 C 和 C++ 源文件生成依赖文件 (.d)。

-R DIR

将运行时路径添加到链接命令中。

-Wl,…

将选项传递给链接器,例如 "-Wl,-rpath=…"。由于逗号会被解释为命令分隔符,因此需要引号。

-W…

将选项传递给汇编器,例如 "-Wa,OPTION"。

-c

仅编译,不链接。

-g

为编译器启用调试选项。

-o FILE
--output FILE

输出文件名。默认扩展名为 .oct(如果指定了 --mex,则为 .mex),除非是链接独立可执行文件。

-p VAR
--print VAR

打印配置变量 VAR。变量分为三类:

用户可以使用环境变量覆盖的 Octave 配置变量。这些变量用于 mkoctfile 执行的命令中。

   ALL_CFLAGS                  INCLUDEDIR
   ALL_CXXFLAGS                LAPACK_LIBS
   ALL_FFLAGS                  LDFLAGS
   ALL_LDFLAGS                 LD_STATIC_FLAG
   BLAS_LIBS                   LIBDIR
   CC                          LIBOCTAVE
   CFLAGS                      LIBOCTINTERP
   CPICFLAG                    LIBOCTMEX
   CPPFLAGS                    OCTAVE_LINK_OPTS
   CXX                         OCTINCLUDEDIR
   CXXFLAGS                    OCTAVE_LIBS
   CXXLD                       OCTAVE_LINK_DEPS
   CXXPICFLAG                  OCTLIBDIR
   DL_LDFLAGS                  OCT_LINK_DEPS
   F77                         OCT_LINK_OPTS
   F77_INTEGER8_FLAG           RDYNAMIC_FLAG
   FFLAGS                      SPECIAL_MATH_LIB
   FPICFLAG                    XTRA_CFLAGS
   INCFLAGS                    XTRA_CXXFLAGS

与上述类似的 Octave 配置变量,但当前未被 mkoctfile 使用。

   AR
   DEPEND_EXTRA_SED_PATTERN
   DEPEND_FLAGS
   FFTW3F_LDFLAGS
   FFTW3F_LIBS
   FFTW3_LDFLAGS
   FFTW3_LIBS
   FFTW_LIBS
   FLIBS
   LIBS
   RANLIB
   READLINE_LIBS

仅用于提供信息的 Octave 配置变量。除了 OCTAVE_HOMEOCTAVE_EXEC_HOME 之外,用户不能覆盖这些变量。

如果在环境中设置了 OCTAVE_HOME 或 OCTAVE_EXEC_HOME,那么其他变量将相应地进行调整,将 OCTAVE_HOME 或 OCTAVE_EXEC_HOME 替换为配置 Octave 时使用的 --prefix--exec-prefix 选项所指定的目录的原始值。

   API_VERSION                 LOCALARCHLIBDIR
   ARCHLIBDIR                  LOCALFCNFILEDIR
   BINDIR                      LOCALOCTFILEDIR
   CANONICAL_HOST_TYPE         LOCALSTARTUPFILEDIR
   DATADIR                     LOCALVERARCHLIBDIR
   DATAROOTDIR                 LOCALVERFCNFILEDIR
   DEFAULT_PAGER               LOCALVEROCTFILEDIR
   EXEC_PREFIX                 MAN1DIR
   EXEEXT                      MAN1EXT
   FCNFILEDIR                  MANDIR
   IMAGEDIR                    OCTAVE_EXEC_HOME
   INCLUDEDIR                  OCTAVE_HOME
   INFODIR                     OCTDATADIR
   INFOFILE                    OCTDOCDIR
   LIBDIR                      OCTFILEDIR
   LIBEXECDIR                  OCTFONTSDIR
   LOCALAPIARCHLIBDIR          OCTINCLUDEDIR
   LOCALAPIFCNFILEDIR          OCTLIBDIR
   LOCALAPIOCTFILEDIR          STARTUPFILEDIR
   LOCALAPIPKGDIR              VERSION
--link-stand-alone

链接一个独立可执行文件。

--mex

假定创建 MEX 文件。将默认输出扩展名设置为 .mex。链接到 liboctmex 而不是 liboctinterp 和 liboctave。

-s
--strip

剥离输出文件。

-v
--verbose

执行命令时回显命令。

file

要编译或链接的文件。可识别的文件类型包括:

   .c    C source
   .cc   C++ source
   .cp   C++ source
   .cpp  C++ source
   .CPP  C++ source
   .cxx  C++ source
   .c++  C++ source
   .C    C++ source
   .f    Fortran source (fixed form)
   .F    Fortran source (fixed form)
   .f90  Fortran source (free form)
   .F90  Fortran source (free form)
   .o    object file
   .a    library file

考虑以下简短示例,它介绍了编写可链接到 Octave 的 C++ 函数的基础知识。

#include <octave/oct.h>

DEFUN_DLD (helloworld, args, nargout,
           "Hello World Help String")
{
  octave_stdout << "Hello World has "
                << args.length () << " input arguments and "
                << nargout << " output arguments.\n";

  // Return empty matrices for any outputs
  octave_value_list retval (nargout);
  for (int i = 0; i < nargout; i++)
    retval(i) = octave_value (Matrix ());

  return retval;
}

第一条关键代码行是 #include <octave/oct.h>,它提供了 C++ oct-file 所需的大部分定义。请注意 octave/oct.h 是一个 C++ 头文件,不能直接在 C 源文件或任何其他语言中使用 #include 包含。

通过 oct.h 包含的是宏 DEFUN_DLD 的定义,该宏用于创建动态加载的函数。此宏接受四个参数:

  1. 在 Octave 中看到的函数名称,
  2. 类型为 octave_value_list 的函数参数列表,
  3. 输出参数的数量——如果不使用,可以(而且通常)省略,以及
  4. 用于函数帮助文本的字符串。

使用 DEFUN_DLD 定义的函数的返回类型始终是 octave_value_list

在选择函数名称时有几个重要的考虑因素。首先,它必须是一个有效的 Octave 函数名,因此必须是由字母、数字和下划线组成的序列,且不能以数字开头。其次,由于 Octave 使用函数名来定义它尝试查找函数的文件名,因此 DEFUN_DLD 宏中的函数名必须与 oct-file 的文件名匹配。因此,上述函数应放在文件 helloworld.cc 中,并将使用以下命令编译为 oct-file:

mkoctfile helloworld.cc

这将创建一个名为 helloworld.oct 的文件,即该函数的编译版本。需要注意的是,在一个源文件中包含多个 DEFUN_DLD 函数是完全允许的。但是,对于源代码中使用 DEFUN_DLD 宏定义的每个函数,必须有一个指向该 oct-file 的符号链接,或者使用 autoload 函数(参见 Function Files),才能使用该函数。

函数的其余部分展示了如何查找输入参数的数量、如何通过 Octave 分页器进行打印,以及如何从函数返回。按照上述方法编译此函数后,其使用示例如下:

helloworld (1, 2, 3)
-| Hello World has 3 input arguments and 0 output arguments.

后续章节将展示如何使用 Octave 核心内部的特定类。像 dMatrix(double 值矩阵)这样的基类可以在 liboctave/array 目录中找到。关于如何使用特定类的最权威参考是头文件本身。不过,通常只需学习手册中的示例就足以掌握如何使用一个类。


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

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