Call embedded interpreter from C++ code compiled with Code Blocks IDE

Compiling and Linking C code that calls Octave funcs from C - missing interpreter and other functions/methods

I am attempting to build a set of C functions available at the following link that purport to all an Octave function to be called from a Cpp program:

Note: there are other topics discussed at that link, but the one of concern is the top most.

The code appears well written but there is no guidance on how to compile and link with Octave code.

I am using the Code Blocks IDE (vsn 20.03) to build this in a C::B project.

The various OCTAVE *.h files that appear to be needed by this code (some nested) use relative addressing into the following paths, which by following the IDE menu structure I listed in C::B Settings:Compiler:Search directories:Compiler (TAB). (That last line represents navigating the C::B menu and Tabs where : denotes the next menu dropdown and TAB is a menu panel)

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\include

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\include\octave-6.4.0\octave

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\include\llvm

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\include\llvm-c

Initially, I got errors for each of these 4 paths, which at least confirmed they were being used. After eliminating the 4 trailing ‘’ characters from the initial list the programs compile fine.

However when I build and run (f9 in the C::B menu, which presumably involves linking), I get error messages like the following:

In reference to line 19 of the calloctave.cc file, which reads:

static octave::interpreter embedded_interpreter;

the build messages report (among many other similar error messages - I am giving only a representative sample here):

In function '__tcf_7':
Line 19 undefined reference to 'octave::interpreter::~interpreter()'

In function 'mexCallOctave'
Line 19 undefined reference to octave::interpreter::interpreter(octave::application)
... 
Line 28 undefined reference to 'mxArray::mxArray(octave_value const&)'
...

followed by many other similar error messages apparently indicating missing object files or methods.

Figuring that the linker was missing the required Octacve libraries (*.o files)) I added the following paths to …/Search directories/Linker (TAB)

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\lib

  • C:\Program Files\GNU Octave\Octave-6.4.0\mingw64\lib\gcc\x86_64-w64-mingw32\9.3.0

  • C:\Program Files\GNU Octave\Octave-6.4.0\usr\lib\python3.8\config-3.8-x86_64-msys

but the same error messages persist.

I expect to see the programs compile link run then call the test octave function:

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

My system

  • OS: e.g. *Windows 10 (Pro 2019)
  • Octave
    >> ver
    ----------------------------------------------------------------------
    GNU Octave Version: 6.4.0 (hg id: 8d7671609955)
    GNU Octave License: GNU General Public License
    Operating System: MINGW32_NT-6.2 Windows 6.2  x86_64
    -----------------------------------------------------------------------
    
  • Installation method: octave-6.4.0-w64-installer.exe

The C code is below:

/*
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.
*/

// calloctave.cc

#include "ExecutionEngine.h"
#include "interpreter.h"
#include "mxarray.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];
}

The article contains guidance how to compile the code. See the description about mkoctfile. In short, mkoctfile is a wrapper to set paths and compiler flags for your system compiler to work (what you seem to struggle with).

Running mkoctfile -p VAR from Octave itself, you can read all necessary compiler flags to configure your own IDE.

The latest example of an embedded interpreter is available from the source repository: