Embedding Octave interpreter in C++ - unexpected output

Hi,
I’m experimenting with embedding the Octave interpreter in C++ (so I can give users runtime model scripting). It sort of works, but I’m getting some unexpected behaviour.

First, I’ve created a test function, which looks like this…

function out = myFunction(params,bulkIn,bulkOut)

fprintf('bulkIn is %d \n',bulkIn);
fprintf('bulkOut is %d \n',bulkOut);

out = [1 2 3  ; params(1) params(2) params(3) ; 5 6 7];

endfunction

Then, I’ve created a c++ function to embed the interpreter, and call the routine twice, just to test it. When I run the code (below), it works fine on the first pass through but the second time it gives a nonsense value (essentially zero) for the second element of the array, with the others being just fine.

Does this have something to do with the fact that I’m trying only to do the initialisation (setting paths etc) on the first pass by making it static and setting an initialisation flag? I’m a bit stuck here and would welcome some help… this almost works except for the strange value of the second element.

The output from the code below is:

Function start:
Value of started is 0
In interpreter initialise loop
bulkIn is 2.073e-06 
bulkOut is 6.35e-06 
Output is  1 2 3
 10 20 30
 5 6 7

Number of elements is  9
element number 0 is 1
element number 1 is 10
element number 2 is 5
element number 3 is 2
element number 4 is 20
element number 5 is 6
element number 6 is 3
element number 7 is 30
element number 8 is 7


Function start:
Value of started is 1
bulkIn is 2.073e-06 
bulkOut is 6.35e-06 
Output is  1 2 3
 1.01362e-316 20 30
 5 6 7

Number of elements is  9
element number 0 is 1
element number 1 is 1.01362e-316
element number 2 is 5
element number 3 is 2
element number 4 is 20
element number 5 is 6
element number 6 is 3
element number 7 is 30
element number 8 is 7

And the code is (sorry - can’t quite work out how to use the code formatting properly here!)

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

using namespace std;

static void octaveCallerFunction() {
	cout << "Function start:" << endl;

	static int started = 0;
	static octave::interpreter interpreter;

	std::cout << "Value of started is "
			<< started
			<< std::endl;

	// check to see if the interpreter has started
	// and initialise it if not.
	if (started == 0) {
		interpreter.initialize_history(false);
		interpreter.initialize();
		interpreter.execute();
		string path = "/home/arwel/eclipseWorkspace_new/functionOctave_new/src";
		octave_value_list p;
		p(0) = path;
		octave_value_list o1 = octave::feval ("addpath", p, 1);
		cout << "In interpreter initialise loop" << endl;
	    started = 1;
	}

    vector<double> pars = {10, 20, 30, 40};
    double bulkIn = 2.073e-6;
    double bulkOut = 6.35e-6;

    Matrix inPars(pars.size(),1);

    for (unsigned int i; i < pars.size(); i++) {
    	inPars(i) = pars.at(i);
    }

    octave_value_list in;
    in(0) = inPars;
    in(1) = octave_value(bulkIn);
    in(2) = octave_value(bulkOut);

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

    if (out.length () > 0)
      std::cout << "Output is "
                << out(0).matrix_value()
                << std::endl;
    else
      std::cout << "invalid\n";

    Matrix v = out(0).matrix_value();
    Array<double> rv = v.as_row();  //Maybe easier to deal with variable sized output as a vector?? (m always = 3)

    // Pointer to start of our row vector
    double *s = rv.fortran_vec();

    octave_idx_type num = rv.dim2();
    int n = num;			// length of the row vector

    cout << "Number of elements is  " << n		// check we get the right value for n
    	<< endl;

    vector<double> vs(num);    // eventually going to put the elements in here....

    // print the values in the array pointed to by s
    for (int i=0; i<n; i++) {
    	cout << "element number "<< i << " is " <<*(s + i) << endl;
     }
    cout << endl;

}

int main(void) {

	octaveCallerFunction();

	std::cout << std::endl;

	octaveCallerFunction();
	return 0;
}

First there is an uninitialized variable in your for-loop, which might explain some ambiguities when running the program:

Second you must properly shutdown the interpreter

// Shutdown the interpreter which cleanly releases all memory.
interpreter->shutdown ();

See for a more complete example in the Octave source repository examples/code/embedded.cc or in the manual the second example with more explanation Standalone Programs (GNU Octave (version 6.1.0)) .

A simple static variable without proper shutdown results in a crash at the end of the program. Best you do the interpreter initialization properly in the main-function and pass a reference to the interpreter instance to your octaveCallerFunction-function.