Octave Wiki | RecentChanges

CategoryExternal

ScaryOctave > CategoryCode > CategoryExternal

Interfacing with other languages

Extending Octave

Octave has good support for interfacing with Fortran/C/C++. The examples subdirectory shows how to add a new function and a new type. There are many more examples in the src/DLD-FUNCTIONS directory as well as in OctaveForge.

Christoph Spiel has written DaCodaAlFine which is also a good introduction, though it is a little out of date.

FIXME Extend DaCodaAlFine with information about OCTAVE_QUIT (a macro you need in your loops to handle Ctrl-C), OCTAVE_LOCAL_BUFFER (a macro to define a temporary buffer which is cleaned when you leave the scope), how to define/set/get global/local/builtin variables and so on.

Paul Thomas has written [Dal Segno al Coda] which extends the DaCodaAlFine for users who aren't experienced in C++.

The CPPQuickReference is a brief summary of matrix operations in Octave and their equivalents in C++ using the Octave libraries. It might make sense in the future to merge this with the wikified Da Coda al Fine document.

There is also a partial support for the mex interface[1] in OctaveForge. This is potentially a great thing to have to help people out of Matlab license hell and get them involved in free software. Ask on the mailing list for advice on filling in the missing functions. The interface is slower than it needs to be because it makes unnecessary copies of the data, but this cost can be reduced with some effort. Complex data has a different internal representation, so extra costs can't be completely eliminated without modifying your code in octave-specific ways. The native Octave inteface is simple to use, so you may want to consider recoding.

Using gdb to debug your extensions

gdb can be used to debug DEFUN_DLD functions. There are N preliminary steps one should during the compilations phase.

With that done, it the shared objects (.oct files) should be ready to go. The debugger can simply be started with 'gdb octave' assuming it is in your path. However, the DEFUN_DLD has not been loaded and therefore gdb cannot set any of the break points or examine it at all. The following steps are not the only solution, but I find them to be effective:

If you find that gdb is not pointing to the line that is being executed or the that the flow of the program is not as expected, then make sure you used the -O0 switch. Octave normally uses the -O2 switch which optimizes the code making it less inituitive for debugging.

Calling GNU Octave functions/m-files from C++

This documentation is attributed heavily to Arjan Vermeij who first raised and explained the issue.

Let us assume that one has an m-file, i.e. the GNU Octave function: exampleOctaveFunction.m

    function [resultScalar, resultString, resultMatrix] = exampleOctaveFunction (inScalar, inString, inMatrix)
       resultScalar = (inScalar * pi);
       resultString = strcat ('Good morning Mr. ', inString);
       resultMatrix = (inMatrix + 1);
    endfunction

The question now is, how does one call the above function from within C++, e.g. from how-to-call-octave.cpp

The easiest way is via feval but one needs to not forget to terminate the octave interpreter via do_octave_atexit ()


    #include <octave/oct.h>
    #include <octave/octave.h>
    #include <octave/parse.h>
    #include <octave/toplev.h> /* do_octave_atexit */
     
    int main (const int argc, char ** argv)
    {
      const char * argvv [] = {"" /* name of program, not relevant */, "--silent"};
       
      octave_main (2, (char **) argvv, true /* embedded */);
      
      octave_value_list functionArguments;
       
      functionArguments (0) = 2;
      functionArguments (1) = "D. Humble";
       
      Matrix inMatrix (2, 3);
       
      inMatrix (0, 0) = 10;
      inMatrix (0, 1) = 9;
      inMatrix (0, 2) = 8;
      inMatrix (1, 0) = 7;
      inMatrix (1, 1) = 6;
       
      functionArguments (2) = inMatrix;
      
      const octave_value_list result = feval ("exampleOctaveFunction", functionArguments, 1);
      
      std::cout << "resultScalar is " << result (0).scalar_value () << std::endl;
      std::cout << "resultString is " << result (1).string_value () << std::endl;
      std::cout << "resultMatrix is\n" << result (2).matrix_value ();
      
      do_octave_atexit ();
     
    }

If you have a Linux machine the following Makefile will perform the building process for you; beware that your directories may be different and you will need to change them accordingly:


    OCTAVE_INCLUDE_DIR=/usr/include/octave-3.0.1/
    OCTAVE_LIB_DIR=/usr/lib/octave-3.0.1/
      
    makefile:
    all: octcall
      
    clean:
       -rm octcall.o octcall
      
    octcall: octcall.o
       g++ -L$(OCTAVE_LIB_DIR) -l octinterp  -o octcall octcall.o
      
    octcall.o: how-to-call-octave.cpp
       g++ -c -I$(OCTAVE_INCLUDE_DIR) -I$(OCTAVE_INCLUDE_DIR)octave -o octcall.o how-to-call-octave.cpp
     

Examples of Extending Octave


CategoryCode