Spec-Zone.ru › Octave 6

A.3 Программы автономного выполнения

Библиотеки, используемые самим Octave, могут быть использованы в автономных приложениях. Эти приложения затем имеют доступ, например, к классам массивов и матриц, а также ко всем алгоритмам Octave. Следующая программа на C++, использует класс Matrix из liboctave.a или liboctave.so.

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

int
main (void)
{
  std::cout << "Hello Octave world!\n";

  int n = 2;
  Matrix a_matrix = Matrix (n, n);

  for (octave_idx_type i = 0; i < n; i++)
    for (octave_idx_type j = 0; j < n; j++)
      a_matrix(i,j) = (i + 1) * 10 + (j + 1);

  std::cout << a_matrix;

  return 0;
}

Для создания автономного приложения можно использовать mkoctfile с такой командой:

$ mkoctfile --link-stand-alone standalone.cc -o standalone
$ ./standalone
Hello Octave world!
  11 12
  21 22
$

Обратите внимание, что приложение standalone будет динамически подключаться к библиотекам Octave и любым вспомогательным библиотекам Octave. Вышеупомянутое позволяет использовать математические библиотеки Octave в приложении. Однако это не позволяет использовать файлы сценариев, файлы oct или встроенные функции Octave в приложении. Для этого необходимо сначала инициализировать интерпретатор Octave. Пример того, как это сделать, можно увидеть в коде

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

int
main (void)
{
  // Create interpreter.

  octave::interpreter interpreter;

  try
    {
      // Inhibit reading history file by calling
      //
      //   interpreter.initialize_history (false);

      // Set custom load path here if you wish by calling
      //
      //   interpreter.initialize_load_path (false);

      // Perform final initialization of interpreter, including
      // executing commands from startup files by calling
      //
      //   interpreter.initialize ();
      //
      //   if (! interpreter.initialized ())
      //     {
      //       std::cerr << "Octave interpreter initialization failed!"
      //                 << std::endl;
      //       exit (status);
      //     }
      //
      // You may skip this step if you don't need to do anything
      // between reading the startup files and telling the interpreter
      // that you are ready to execute commands.

      // Tell the interpreter that we're ready to execute commands:

      int status = interpreter.execute ();

      if (status != 0)
        {
          std::cerr << "creating embedded Octave interpreter failed!"
                    << std::endl;
          return status;
        }

      octave_idx_type n = 2;
      octave_value_list in;

      for (octave_idx_type i = 0; i < n; i++)
        in(i) = octave_value (5 * (i + 2));

      octave_value_list out = octave::feval ("gcd", in, 1);

      if (out.length () > 0)
        std::cout << "GCD of ["
                  << in(0).int_value ()
                  << ", "
                  << in(1).int_value ()
                  << "] is " << out(0).int_value ()
                  << std::endl;
      else
        std::cout << "invalid\n";
    }
  catch (const octave::exit_exception& ex)
    {
      std::cerr << "Octave interpreter exited with status = "
                << ex.exit_status () << std::endl;
    }
  catch (const octave::execution_exception&)
    {
      std::cerr << "error encountered in Octave evaluator!" << std::endl;
    }

  return 0;
}

который, как и прежде, компилируется и выполняется как автономное приложение с помощью

$ mkoctfile --link-stand-alone embedded.cc -o embedded
$ ./embedded
GCD of [10, 15] is 5
$

Стоит повторить, что если из автономной программы на C++ необходимо вызывать только встроенные функции, то нет необходимости инициализировать интерпретатор. Общее правило состоит в том, что для встроенной функции с именем function_name в интерпретаторе будет существовать функция C++ с именем Ffunction_name (обратите внимание на добавленный заглавный F) доступная в API C++. Объявления всех встроенных функций собраны в заголовочном файле builtin-defun-decls.h. Это свойство следует использовать с осторожностью, так как список встроенных функций может изменяться. Нет гарантий, что функция, которая сейчас является встроенной, не будет реализована как файл .m или как динамически подключаемая функция в будущем. Пример вызова встроенных функций из C++ можно увидеть в коде

#include <iostream>
#include <octave/oct.h>
#include <octave/builtin-defun-decls.h>

int
main (void)
{
  int n = 2;
  Matrix a_matrix = Matrix (n, n);

  for (octave_idx_type i = 0; i < n; i++)
    for (octave_idx_type j = 0; j < n; j++)
      a_matrix(i,j) = (i + 1) * 10 + (j + 1);

  std::cout << "This is a matrix:" << std::endl
            << a_matrix            << std::endl;

  octave_value_list in;
  in(0) = a_matrix;

  octave_value_list out = Fnorm (in, 1);
  double norm_of_the_matrix = out(0).double_value ();

  std::cout << "This is the norm of the matrix:" << std::endl
            << norm_of_the_matrix                << std::endl;

  return 0;
}

который компилируется и выполняется как автономное приложение с помощью

$ mkoctfile --link-stand-alone standalonebuiltin.cc -o standalonebuiltin
$ ./standalonebuiltin
This is a matrix:
 11 12
 21 22

This is the norm of the matrix:
34.4952
$

© 1996–2022 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v6.4.0/Standalone-Programs.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API