Instantiate an instance of C++ object via MATLAB Coder

5 vues (au cours des 30 derniers jours)
Maksims Abalenkovs
Maksims Abalenkovs le 1 Mar 2021
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 commentaires
Maksims Abalenkovs
Maksims Abalenkovs le 4 Mar 2021
Modifié(e) : Maksims Abalenkovs le 4 Mar 2021
Here is another iteration of my MATLAB function intended for Coder:
function [status] = inter_c() %#coder
%INTER_C Initialises Octave interpreter
% Initialises Octave interpreter
coder.updateBuildInfo('addCompileFlags', '-I/opt/local/include/octave-6.1.0/octave');
coder.updateBuildInfo('addIncludeFiles', 'oct.h');
coder.updateBuildInfo('addIncludeFiles', 'octave.h');
coder.updateBuildInfo('addIncludeFiles', 'parse.h');
coder.updateBuildInfo('addIncludeFiles', 'interpreter.h');
coder.updateBuildInfo('addLinkObjects', 'liboctave.lib', '/opt/local/lib/octave/6.1.0/', '', true, true);
coder.updateBuildInfo('addLinkObjects', 'liboctinterp.lib', '/opt/local/lib/octave/6.1.0/', '', true, true);
coder.updateBuildInfo('addSourceFiles', 'inter.cpp');
coder.updateBuildInfo('addIncludeFiles', 'inter.h');
coder.cinclude('oct.h');
coder.cinclude('octave.h');
coder.cinclude('parse.h');
coder.cinclude('interpreter.h');
coder.cinclude('inter.h');
inter = coder.opaque('octave::interpreter', 'HeaderFile', '/opt/local/include/octave-6.1.0/octave/interpreter.h');
status = 0;
status = coder.ceval('initOctInter', coder.ref(inter));
end
I would like to pass the Octave intepreter instance called `inter` by reference. Since it is C++ the `initOctInter` signature is:
#include <octave.h>
#include <interpreter.h>
using namespace octave;
int initOctInter(interpreter &inter);
// @eof inter.h
Please see the StackOverflow answer of Sean Ramey for an example.
My new attempt still crashes with the following error:
codegen inter_c -lang:c++ -args {} -report
??? Variable 'inter' is not fully defined on some execution paths.
For completeness please find below the contents of `inter.cpp` file and `test_inter.cpp` (native C++ code for calling Octave interpreter):
#include <iostream>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>
using namespace std;
using namespace octave;
// Initialises Octave interpreter
int initOctInter(interpreter &inter) {
int status = -1;
try {
status = inter.execute();
}
catch (const exit_exception& ex) {
}
catch (const execution_exception&) {
}
return status;
}
// @eof inter.cpp
C++ source code of `test_inter.cpp`:
#include <iostream>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>
#include "inter.h"
using namespace std;
using namespace octave;
int main(int argc, char *argv[]) {
interpreter inter;
int status = initOctInter(inter);
cout << "status:" << status << endl;
// Shutdown interpreter
inter.shutdown();
return 0;
}
// @eof test_inter.cpp
Maksims Abalenkovs
Maksims Abalenkovs le 4 Mar 2021
Changing `coder.ref(inter)` to `coder.wref(inter)` makes Coder crash with another error:
inter_c.cpp:31:10: error: no matching function for call to 'initOctInter'
return initOctInter(&inter);
^~~~~~~~~~~~
/Users/mabalenk/repo/git/alc/rascal/oct/inter.h:6:5: note: candidate function not viable: no known conversion from 'octave::interpreter *' to 'octave::interpreter &' for 1st argument; remove &
int initOctInter(interpreter &inter);
But I don't believe this is a correct approach.

Connectez-vous pour commenter.

Réponses (2)

Shadaab Siddiqie
Shadaab Siddiqie le 4 Mar 2021
From my understanding you want to Instantiate an instance of C++ object. Refer similar answer which might help you.
  1 commentaire
Maksims Abalenkovs
Maksims Abalenkovs le 4 Mar 2021
I was hoping to avoid writing custom wrappers to C++ functions. I wanted to call basic interface functions similar to `initOctInt()` and pass them the instance of an object and let native C++ deal with the object methods. But it seems I will still have to go that route. I feel it is too complicated for an average MATLAB user. Time to study your `person` example.

Connectez-vous pour commenter.


Darshan Ramakant Bhat
Darshan Ramakant Bhat le 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 commentaires
Darshan Ramakant Bhat
Darshan Ramakant Bhat le 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
Maksims Abalenkovs le 8 Mar 2021
Modifié(e) : Maksims Abalenkovs le 8 Mar 2021
Thank you @Darshan Ramakant Bhat for your suggestion. But this is a very intrusive solution, that I would like to avoid for now. I made an inquiry about it on the GNU Octave mailing list. Let's see, what they respond. Otherwise, we will have to take this route ;)

Connectez-vous pour commenter.

Catégories

En savoir plus sur Oil, Gas & Petrochemical dans Help Center et File Exchange

Produits


Version

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by