Instantiate an instance of C++ object via MATLAB Coder
Show older comments
I have an interesting task. I would like to call a GNU Octave interpreter via MATLAB Coder. I have custom C++ source code that initialises and prepares Octave interpreter. My current problem lies in making MATLAB coder aware of the C++ `interpreter` instance. Please find below by current attempt:
function [status] = inter_c() %#coder
%INTER_C Initialises Octave interpreter
% Initialises Octave interpreter
coder.cinclude('/opt/local/include/octave-6.1.0/octave/oct.h');
coder.cinclude('/opt/local/include/octave-6.1.0/octave/interpreter.h');
coder.updateBuildInfo('addSourceFiles', 'inter.cpp');
inter = coder.opaque('octave::interpreter'); % <-- error occurs here
status = 0;
status = coder.ceval('initOctInter', coder.ref(inter));
end
When I try to generate the resulting C++ code with
codegen inter_c -lang:c++ -args {} -report
It crashes with the following error:
??? Variable 'inter' is not fully defined on some execution paths.
I understand, that I need to let MATLAB coder know all the details of the `interpreter` definition, but I don't know, how to do that correctly. I also tried to direct coder to the relevant header file with
inter = coder.opaque('interpreter', 'HeaderFile', '/opt/local/include/octave-6.1.0/octave/interpreter.h');
But the error remains the same.
The contents of custom C++ code in `inter.cpp` are:
#include <iostream>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>
// Initialises Octave interpreter
int initOctInter(interpreter &inter) {
int status = -1;
// Inhibit reading history file
inter.initialize_history(false);
// Set custom load path
inter.initialize_load_path(false);
// Initialise interpreter
inter.initialize();
status = (inter.initialized()) ? 0 : -1;
if (status != 0) {
cerr << "Octave interpreter initialisation failed!" << endl;
}
// Make interpreter ready to execute
status = inter.execute();
if (status != 0) {
cerr << "Creating embedded Octave interpreter failed!" << endl;
}
return status;
}
In C++ this task is achieved as follows:
#include <interpreter.h>
int main(void) {
interpreter inter;
// Initialise Octave interpreter
int status = initOctInter(inter);
if (status == 0) {
// Call compute functions
// ...
// Shutdown Octave interpreter (releases memory)
inter.shutdown();
}
return 0;
}
I would appreciate any help and guidance. If possible, would you please direct me to a relevant example? Thank you!
12 Comments
Darshan Ramakant Bhat
on 2 Mar 2021
I am not very sure what is happening here.
Can you please try to initialize your variable used for "coder.opaque" like shown in the "FILE *" example :
You may have to change the code like below :
coder.opaque('octave::interpreter*','nullptr','HeaderFile', '/opt/local/include/octave-6.1.0/octave/interpreter.h')
Then change the interface like below :
int initOctInter(interpreter* inter) {...}
This is just my guess, cannot guarantee you that this will work.
Darshan Ramakant Bhat
on 2 Mar 2021
Another thing to try out.
Try to have an initialization for the opaque variable.
inter = coder.opaque('octave::interpreter');
inter = coder.ceval('init_interpreter'); % Initializes the variable
Maksims Abalenkovs
on 2 Mar 2021
Maksims Abalenkovs
on 2 Mar 2021
Darshan Ramakant Bhat
on 3 Mar 2021
I guess MATLAB Coder is not able to determine that the variable "inter" is being assigned. The assignment is being done through coder.ref() indirectly, but I am suspecting that the MATLAB Coder is not able to see that.
By doing coder.opaque(), you are just declaring the type, you are not acutally instantiating the object according to my understanding. So I guess you will have to care of the actual allocation of the object.
For example in your previous question "create_point" was actually creating the struct and returing it. I guess you will have to do the similar thing here.
Maksims Abalenkovs
on 3 Mar 2021
Maksims Abalenkovs
on 3 Mar 2021
Edited: Maksims Abalenkovs
on 3 Mar 2021
Maksims Abalenkovs
on 3 Mar 2021
Maksims Abalenkovs
on 3 Mar 2021
Darshan Ramakant Bhat
on 4 Mar 2021
Did you try using coder.wref() instead of coder.ref() ?
Maksims Abalenkovs
on 4 Mar 2021
Edited: Maksims Abalenkovs
on 4 Mar 2021
Maksims Abalenkovs
on 4 Mar 2021
Answers (2)
Shadaab Siddiqie
on 4 Mar 2021
1 vote
From my understanding you want to Instantiate an instance of C++ object. Refer similar answer which might help you.
1 Comment
Maksims Abalenkovs
on 4 Mar 2021
Darshan Ramakant Bhat
on 4 Mar 2021
I tried to solve this issue by creating the similar example.
I have mocked up some of the files using my own definition of the interpreter. Please go through the attached code.
I guess you were almost there using coder.wref(), only thing was you need to change your interface to take pointer (*) not as referece (&).
Hope this will be helpful for you.
codegen inter_c -lang:c++ -args {} -report
8 Comments
Maksims Abalenkovs
on 4 Mar 2021
Maksims Abalenkovs
on 4 Mar 2021
Darshan Ramakant Bhat
on 4 Mar 2021
I guess that definition is getting included due to the below code
coder.cinclude('oct.h');
coder.cinclude('octave.h');
coder.cinclude('parse.h');
coder.cinclude('interpreter.h');
coder.cinclude('inter.h');
One of the header included here may include the above header by transitive closure.
You can inspect the generated code, those should include only above mentioned headers.
Maksims Abalenkovs
on 4 Mar 2021
Edited: Maksims Abalenkovs
on 4 Mar 2021
Maksims Abalenkovs
on 4 Mar 2021
Maksims Abalenkovs
on 4 Mar 2021
Darshan Ramakant Bhat
on 5 Mar 2021
The problem looks to be that both the definitions are reachable. I cannot think of a good solution unless you rename the definition in ov.h
Maksims Abalenkovs
on 8 Mar 2021
Edited: Maksims Abalenkovs
on 8 Mar 2021
Categories
Find more on Octave in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!