Instantiate an instance of C++ object via MATLAB Coder

조회 수: 6 (최근 30일)
Maksims Abalenkovs
Maksims Abalenkovs 2021년 3월 1일
편집: Maksims Abalenkovs 2021년 3월 8일
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
Maksims Abalenkovs
Maksims Abalenkovs 2021년 3월 4일
편집: Maksims Abalenkovs 2021년 3월 4일
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 2021년 3월 4일
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.

댓글을 달려면 로그인하십시오.

답변 (2개)

Shadaab Siddiqie
Shadaab Siddiqie 2021년 3월 4일
From my understanding you want to Instantiate an instance of C++ object. Refer similar answer which might help you.
  댓글 수: 1
Maksims Abalenkovs
Maksims Abalenkovs 2021년 3월 4일
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.

댓글을 달려면 로그인하십시오.


Darshan Ramakant Bhat
Darshan Ramakant Bhat 2021년 3월 4일
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
Darshan Ramakant Bhat
Darshan Ramakant Bhat 2021년 3월 5일
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 2021년 3월 8일
편집: Maksims Abalenkovs 2021년 3월 8일
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 ;)

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Octave에 대해 자세히 알아보기

제품


릴리스

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by