How to pass a class to MATLAB executable

This is a follow up to my previous here.
I have the following script
main.m >>
function m = magicsquare
n = setting.n;
if ischar(n)
n=str2double(n);
end
m = magic(n);
disp(m)
and a class from which the variable n is read by the above script.
classdef setting
%SETTING Summary of this class goes here
% Detailed explanation goes here
properties(Constant)
n = 5;
end
% methods
% function obj = setting(inputArg1,inputArg2)
% %SETTING Construct an instance of this class
% % Detailed explanation goes here
% obj.Property1 = inputArg1 + inputArg2;
% end
%
% function outputArg = method1(obj,inputArg)
% %METHOD1 Summary of this method goes here
% % Detailed explanation goes here
% outputArg = obj.Property1 + inputArg;
% end
% end
end
I have converted main.m into a executable using the Application compiler. Since I want the user to specify input in `setting` class, this class was not converted into a binary during compilation (i.e. I have excluded the setting.m file from `Files required for your application to run` tab in the Application compiler.)
Here is what I tried: I simply saved main.exe and setting.m class in the same folder and ran !main.
I get the following error
Unable to resolve the name setting.n.
Error in main (line 2)
MATLAB:undefinedVarOrClass
I could have passed `n` as an input argument to the executable like mentioned in my previous post since `n` is a single property defined in setting class. However for my real system , there are more properties defined in settings and I want the user to define all the properties in a single class file from which the rest of functions can access the property values defined. I am not sure how to pass a class to the `main` executable. Suggestions will be really helpful.

 Accepted Answer

You cannot do that.
Any .m or .p file (script, function, class definition) that is not completely defined at the time of compilation, would have to be interpreted at run-time of the executable. However, compiled executables have no ability to interpret MATLAB.
If you want the user to be able to provide settings in a file, then you will need to have them do that in the form of a data file that your program analyzes to set up its variables.

8 Comments

@Walter Roberson Thanks a lot for the details.
I downloaded and tried to run the iniconfig.m file available in the link shared above. The input in the .ini file can be read and
; example.ini -- INI file example for the class INiConfig
; UPD: 21.03.2010
; Supported whitespaces in section names
[Section 1] ; allowed the comment to section
key11=10 ; numeric scalar
key12=1.45, 19.5, 0.6, -1.4 ; numeric vector
key13=1.5+3i, -2-2i ; complex numeric vector
key14=Hello, Matlab! ; string
IniConfig.m
ini = IniConfig();
ini.ReadFile('example.ini')
sections = ini.GetSections()
[keys, count_keys] = ini.GetKeys(sections{1})
values = ini.GetValues(sections{1}, keys)
values =
4×1 cell array
{[ 10]}
{[ 1.4500 19.5000 0.6000 -1.4000]}
{[1.5000 + 3.0000i -2.0000 - 2.0000i]}
{'Hello, Matlab!' }
I have a few doubts
Instead of `classdef setting` should I create a .ini file with all the settings ? Should I compile IniConfig.m along with the other files and generate the executable?
IniConfig.m
ini = IniConfig();
That would be an infinite loop, since you are calling IniConfig from IniConfig
But yes, the general idea is that you would compile in that File Exchange Contribution or code to similar effect, and doing so would give you a user-friendly-ish way of allowing users to change initialization files.
The classdef that you had earlier cannot work outside of the compiled executable. However it is possible that you have designed your code in a way that expects variables of class setting and if so then you would compile class setting as part of your executable and have your code that read initialization files set properties of that class.
"However it is possible that you have designed your code in a way that expects variables of class setting "
Yes, the other functions in my complied code require the variables of class settings.
"if so then you would compile class setting as part of your executable and have your code that read initialization files set properties of that class."
I'm not really sure how to set the properties of the class by reading the values from the ini file. Could you please offer some suggestions? Should I read the initialization file within the class `settings` by defining a method in setting that reads the input file by calling ini = IniConfig();?
You could certainly do the reading during the constructor -- so, yes, method setting within class setting .
After that it would be a matter of fishing through the ini you get from parsing the file, and using the result to decide which class properties to set to which values. (You would want the keys and values from the ini file as the keys help you decide which property the values are associated with.)
I tried the following
classdef setting
%SETTING Summary of this class goes here
% Detailed explanation goes here
properties(Constant)
n = setting.load_setting("n");
end
methods(Static)
function obj = load_setting(key)
ini = IniConfig();
ini.ReadFile('example.ini')
sections = ini.GetSections()
[keys, count_keys] = ini.GetKeys(sections{1})
values = ini.GetValues(sections{1}, keys)
% values = ini.GetValue(sections{1}, key)
end
end
end
I could get all the keys and values present in a section of the initialization file via the GetKeys method (please see below) defined in IniConfig.
function [key_names, count_keys] = GetKeys(obj, section_name)
%GetKeys - get names of all keys from given section
%
% Using:
% key_names = GetKeys(section_name)
% [key_names, count_keys] = GetKeys(section_name)
%
% Input:
% section_name - name of section
%
% Output:
% key_names - cell array with the names of keys
% count_keys - number of keys in given section
% -------------------------------------------------------------
error(nargchk(2, 2, nargin));
section_name = obj.validateSectionName(section_name);
[key_names, count_keys] = obj.getKeys(section_name);
end
However, I am not sure how to get the value corresponding to a single key. For instance, I want to do
properties(Constant)
n = setting.load_setting("n");
end
%(commented in the method mentioned above; this method is not present
%in IniConfig class.
values = ini.GetValue(sections{1}, key)
I'd like to create a method for parsing the value of a key or zip keys and values obtained from the following. This would be similar to a dict in python but I am not sure how to do this in MATLAB. Suggestions wll be really helpful.
[keys, count_keys] = ini.GetKeys(sections{1})
values = ini.GetValues(sections{1}, keys
[is_it_there, idx] = ismember("n", keys)
if is_it_there
associated_value = values{idx};
end
Probably the closest MATLAB construct to python dict is containers.Map, which allows you to index the map object at a string and get back the corresponding value.
I magaged to read structs from initialization files using [this]( https://in.mathworks.com/matlabcentral/fileexchange/55766-ini ) to set up the following
Now, I've the following class
classdef setting
%SETTING Summary of this class goes here
% Detailed explanation goes here
properties(Constant)
n = setting.get_n;
q = setting.get_q;
end
methods(Static)
function data = load_setting
File = 'Configuration.ini';
I = INI('File',File);
I.read();
data = I.get('UserData'); % struct
end
function n = get_n
n = data.m + 2;
end
function q = get_q
temp = data.q;
q = fieldnames(q);
end
end
end
I'm looking for a way to easily access `data` returned by load_setting in the rest of the methods defined in the class. Suggestions will be really helpful.
temp = data.q;
q = fieldnames(q);
You do not do anything with temp and then in the next line you use the undefined variable q
Your code is assuming that the ini file is giving back properties m and q but you should not be assuming that. You should be validating every necessary property (and for any optional properties you should be checking that they exist when the user asks for them.)
classdef setting
Class name is setting
methods(Static)
function data = load_setting
Method name is something different than setting, so that method is not the class constructor.
function n = get_n
n = data.m + 2;
end
data is not a property of the class, and does not appear to be the name of a class or package. data is probably not defined in that context.
function data = load_setting
File = 'Configuration.ini';
I = INI('File',File);
I.read();
data = I.get('UserData'); % struct
end
That's a static class, and besides setting is not a handle class, so load_setting is going to return the values to whichever function calls it. You never call the function and store the results anywhere, so the data local variable there is disconnected from the use of data in your two get_* functions.
properties(Constant)
n = setting.get_n;
q = setting.get_q;
end
Okay, you are defining constants, and it looks like you intend to call methods of your class in order to do so. So, exactly when are those methods going to be called?
MATLAB evaluates the expressions when loading the class.
Your get_n and get_q expect data to have been constructed already, which implies that they expect load_setting to be called already. But load_setting does not get called automatically, since it is just an ordinary method.
If the content of load_setting was the constructor method, then there would be the issue that constructor methods are called when an instance is created, not when the class is loaded. At the moment I do not find any special method that are triggered when the class is loaded, but I am not at all experienced in that topic.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!