How to Embed the Gnu Octave in C/C++ Program

Call GNU Octave functions in C?

There is a c mex interface. However the octave interpreter must be embedded and initialized before any mex function can be called. As of Octave 4.4 octave_main as suggested by the linked answer has been deprecated and some other changes also are needed for it to be useful for mex programs. So I have prepared a c++ source file calloctave.cc containing the functions mexCallOctave and free_arg_list and its header calloctave.h.

calloctave.cc

// calloctave.cc

#include "interpreter.h"
#include "mxarray.h"
#include "parse.h"

extern "C"
int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
mxArray *argin[], const char *fname)
{

static octave::interpreter embedded_interpreter;
if (!embedded_interpreter.initialized())
embedded_interpreter.execute ();

octave_value_list args;

args.resize (nargin);

for (int i = 0; i < nargin; i++)
args(i) = mxArray::as_octave_value (argin[i]);

bool execution_error = false;

octave_value_list retval;

retval = octave::feval (fname, args, nargout);

int num_to_copy = retval.length ();

if (nargout < retval.length ())
num_to_copy = nargout;

for (int i = 0; i < num_to_copy; i++)
{
argout[i] = new mxArray (retval(i));
}

while (num_to_copy < nargout)
argout[num_to_copy++] = nullptr;

return execution_error ? 1 : 0;
}

extern "C"
void
free_arg_list (int nargs, mxArray* arglist[])
{
for(int i = 0; i < nargs; i++)
delete arglist[i];
}

calloctave.h

// calloctave.h
#pragma once
#include "mex.h"

#if defined (__cplusplus)
extern "C" {
#endif

int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
mxArray *argin[], const char *fname);
void
free_arg_list (int nargs, mxArray* arglist[]);

#if defined (__cplusplus)
}
#endif

Here is a basic introduction into mex files. You can compile an example hello world program adding the option --verbose as mkoctfile --mex --verbose hello.c to get the list of compiler options that you need to use them for compilation of your actual programs. Note that because calloctave.cc is a c++ source it should be compiled using a c++ compiler such as g++.
In the following example a m function "myfunction" is called. It gets one input and produces one output. mexCallOctave is used for calling the octave function and it has the same signature as mexCallMATLAB.

myfunction.m

% myfunction.m
function out= myfunction( a )
out = sum(a);
endfunction

main.c

//main.c
#include <stdio.h>
#include "calloctave.h"
int main()
{
double input_data[] = {0,1,2,3,4,5,6,7,8,9,10};

const int nargin = 1;
const int nargout = 1;
mxArray* rhs[nargin];
mxArray* lhs[nargout];

// allocate mex array
rhs[0] = mxCreateDoubleMatrix( 10, 1, mxREAL);
double* rhs_ptr = mxGetPr( rhs[0] );

// copy data from input buffer to mex array
for (int i = 0 ; i < 10; i++)
rhs_ptr[i] = input_data[i];

// call octave function
mexCallOctave(nargout, lhs, nargin, rhs, "myfunction");

double* lhs_ptr = mxGetPr( lhs[0] );

double output_data = *lhs_ptr;

// show the result
printf ("result = %f", output_data);

// free memory

mxDestroyArray(rhs[0]);
free_arg_list(nargout, lhs);
}

Using octave built-in function in C

#include <iostream>

should be

#include <stdio.h>

and

std::cout << a_matrix;

should be

printf("%d", a_matrix);

But <octave/oct.h> can not be used in C:

A.1.1 Getting Started with Oct-Files

The first critical line is #include which makes
available most of the definitions necessary for a C++ oct-file. Note
that octave/oct.h is a C++ header and cannot be directly #include’ed
in a C source file, nor any other language.

Alternative:

The interface is centered around supporting the languages C++, C, and
Fortran. Octave itself is written in C++ and can call external C++/C
code through its native oct-file interface. The C language is also
supported through the mex-file interface for compatibility with
MATLAB. Fortran code is easiest to reach through the oct-file
interface.

How to import octave implementation to C++ or C#

What you are probably looking for is Dynamically Linked Functions.

Octave has the possibility of including compiled code as dynamically
linked extensions and then using these extensions as if they were part
of Octave itself. Octave can call C++ code through its native oct-file
interface or C code through its mex interface. It can also indirectly
call functions written in any other language through a simple wrapper.
The reasons to write code in a compiled language might be either to
link to an existing piece of code and allow it to be used within
Octave, or to allow improved performance for key pieces of code.

For the reverse, see here.

Integrating Octave interpreter into program compiled with GCC 4.8.1

I just learned that there is a newer Octave version available at http://mxeoctave.osuv.de/ which was compiled with GCC 4.9.2. This version of GCC works for me perfectly and the second example provided in the documentation started to work when compiled with g++ provided with the distribution.

Store C++ data to octave using a data interface?

This is probably not an answer for you, but writing it as a comment was too long and dense, so I'm writing as an answer for convenience, plus hopefully while trying to clarify things it may provide you with an answer anyway.

Essentially, there is some confusion in your question. It's worth clarifying these points first. If my comments here don't answer your question, perhaps you can edit your question to clarify what you want exactly based on my comments below.

  1. Matlab offers two interfaces, one for C and one for C++. These are completely separate interfaces.

  2. These are general interfaces, for writing a function in, say, C, and calling that function from matlab, or vice versa. They are not for "exporting data". It may be possible to store data from within C code into a .mat by calling the matlab "save" function via the provided api, but I can't think of a good reason to do this via C rather than as part of a matlab script which calls a C-written function to process some data, and then calls 'save' from matlab to save the result.

  3. Octave supports matlab's "C" interface (so called ".mex" files). It does not support matlab's "C++" interface. But it does have its own "C++" interface, namely ".oct" files.

  4. If you have an example of a .mex file which performs what you ask, then presumably it can also be compiled in octave with little to no modification (except for including the right library names to reflect octave headers).

  5. "I can call external routines from Octave" <-- you can assign general C++ code a function name and transform it, so that you can call it from octave. More to the point though, you can pass this function inputs from octave, let it handle the computations in C++, and then return a result back to octave. Is this what you mean by this? If so, then yes, this is possible, and the manual section you linked has examples of how to do this (btw, note that you are linking to an older version, the newest version of the manual is octave.org/doc/v5.2.0 )

  6. Octave also provides an interface for calling Octave functions directly from C++ code (whether in the context of .oct files intended for use within octave, or in the context of standalone C++ executables which would like to use octave functions inside).

When you say "store data", it seems to me that you are basically asking about point No.5, i.e. pass data as an input to a c++ written function, have c++ do something with that data, and then return its result back to the octave workspace. Is that correct? Or are you literally asking for a way to create a .mat file from within c++ specifically?

If what you're asking for is simply the former, then the manual provides many examples. E.g. if you wanted to try the one near the end of this page: https://octave.org/doc/v5.2.0/Matrices-and-Arrays-in-Oct_002dFiles.html#Matrices-and-Arrays-in-Oct_002dFiles, then say that code is saved in file addtwomatrices.cpp, then you can compile (e.g. from your linux terminal) it like so:

$ mkoctfile -c addtwomatrices.cpp
$ mkoctfile ./addtwomatrices.o -o ./addtwomatrices

And then call it from octave like so:

> addtwomatrices( eye(2), magic(2) )
ans =
5 3
1 3

UPDATE

Here is an example of creating a matrix directly from C++ and then saving it to an octave-compatible format.

// in testmat.cpp
# include <octave/oct.h>
# include <octave/ls-oct-text.h> /* defines save_text_data */

int main ()
{
// Create a matrix and fill it with values
Matrix M(3,3);
for (int i = 0; i < 9; ++i ) { M.elem(i) = i+1.; }

// Save to disk
std::ofstream out_file_stream( "out.mat" );
save_text_data ( out_file_stream,
octave_value(M),
std::string("M_matrix"), // variable name
true, // mark as global?
5 // precision
);

out_file_stream.close();
}

Compile, link, and run:

mkoctfile -c testmat.cpp
mkoctfile --link-stand-alone -o testmat testmat.o
LD_LIBRARY_PATH=/opt/octave-5.2.0/lib/octave/5.2.0 ./testmat # change path accordingly

Confirm from octave out.mat was saved properly and can be opened in octave:

octave:1> load out.mat
octave:2> M_matrix
M_matrix =
1 4 7
2 5 8
3 6 9


Related Topics



Leave a reply



Submit