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
//
// int status 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/v5.2.0/Standalone-Programs.html