Calling static method from m-file (octave/matlab) - matlab

I am currently having problems calling a static method located in an m-file, through the octave command interface. The error I'm getting is error: invalid call to script path/to/Test.m
Test.m:
classdef Test
methods(Static=true)
function ret = test_function()
ret = 0;
end
end
end
I am trying to call the method in the following way: > Test.test_function(). It's important to note that the script resides in the same directory in which I invoked the octave command, the script Test.m shows up using tab completion so the location is not at fault here I guess.
Any help is much appreciated,
thanks in advance!

From the Octave FAQ: "Matlab classdef object oriented programming is not yet supported, though work is underway in a branch of the development tree."
So the error is likely arising from the lack of classdef support, and the parser can't make sense of the call at all.

Related

Will Matlab respond exceptions raised from VS compiled DLL?

Here's a brief summary for what happened: basically, I'm trying to rewrite a MATLAB program to a C# program, where both of them utilized function implemented in a VS compiled library.
For Matlab:
val = MyDLL.MyFunc(int32(a),int32(b),int32(c),int32(d));
Where:
MyDLL= actxserver('MyLib.MyClass');
As in C#, it's directly calling the function:
obj = new MyLib.MyClass;
val = obj.MyFunc(int32(a),int32(b),int32(c),int32(d));
However, in C# program, an exception from MyFunc would be raised but in MATLAB program nothing happens. Since they are essentially calling the same function from the same library, I reckon whether it could be the reason that MATLAB doesn't actually respond to exception raised from outer library?
Any advice would be helpful, thanks!
P.S.: All arguments match with each other and both programs are absolutely calling the very same function.

Can I detect MATLAB termination other than by way of a mex file mexAtExit handler?

tl;dr
Is there any way in a Matlab .m file to detect that Matlab termination is under way?
I have an unmanaged library that provides an interface to my product. I have wrapped that for Matlab using a mex file. So my unmanaged library exists as a Windows DLL. I have a mex file that wraps that. In turn I have a collection of Matlab classes, implemented in various .m files that wrap the mex file. So far so good, all of this works splendidly.
I recently became aware of a problem during Matlab shutdown. Some of the Matlab classes wrap unmanaged objects. These unmanaged objects need to be destroyed when they are no longer needed. So I implement delete functions for the Matlab classes that wrap the unmanaged objects, and call into the mex file to destroy the objects. Obviously the mex file simply forwards these destruction calls to the unmanaged library. Again, this all works just fine.
The problem arises when Matlab shuts down and the user's workspace contains Matlab objects wrapping the unmanaged objects. Unfortunately, Matlab unloads the mex file, and then destroys the objects in the workspace. What happens next is that the delete function executes which calls into the mex file. Which reloads the mex file that was just unloaded. And now the attempt to destroy the unmanaged object leads to runtime errors, because my library has to be re-loaded.
Since is going to unload the mex file before destroying workspace objects, I have no choice but to skip the deletion of the unmanaged objects in that scenario. It isn't a memory leak or indeed a problem in any way, since the process is terminating. However, I do need to detect that the process is terminating. Which leads to the question, how to do that.
I'm aware of the finish.m termination file, but I'm not in control of that since I am providing a library. The user controls their termination file, and so I've ruled out that option. I don't even know whether or not it runs at a suitable time, i.e. before the workspace objects are destroyed.
I've built a functioning solution using mexAtExit. In the mex file initialization I call mexAtExit like so:
mexAtExit(atExit);
The atExit function is:
void atExit(void)
{
mexCallMATLAB(0, NULL, 0, NULL, "mylib.atExit");
}
And ofx.atExit is in the Matlab code and is implemented like this:
methods(Static)
function atExit
mylib.mexHasUnloaded(true);
end
function result = mexHasUnloaded(varargin)
global mexHasUnloadedGlobalVar;
if isempty(mexHasUnloadedGlobalVar)
mexHasUnloadedGlobalVar = false;
end
if nargin > 0
mexHasUnloadedGlobalVar = varargin{1};
end
result = mexHasUnloadedGlobalVar;
end
....
end
The delete function then checks mexHasUnloaded like this:
function delete(self)
if ~mylib.mexHasUnloaded
mylibMex(mylib.mexDestroyObject, self.handle);
end
end
Whilst this appears to work, I'm not at all happy with it.
Can I really only detect Matlab termination from inside a mex file? I would like to detect this directly in the .m file and it feels like that ought to be possible. Is it possible?
Do I really need to use a global variable like that? Can't I find a better way to look after this state? I tried using a persistent variable but that was just as hacky and did not work. The persistent variable was re-initialised at some point during the termination which meant that mexHasUnloaded started returning false after it had earlier been set to true.
Or is there a different solution to my problem? Can I force my mex file to stay loaded until after the workspace objects are deleted?
Does it work to mexLock() your MEX file so that it doesn't get unloaded, so the delete methods can do the right thing at shutdown?

Variable Declaration with the Presence of Nested Functions

Someone on /r/matlab asked me a really interesting question a few days ago related to a Flappy Bird clone submitted to the MATLAB FEX. The poster noticed that if you open the main .m file, stop it in the debugger on the first line, and run a whos(), you see a bunch of variables before they are explicitly defined by the function.
The first thing that I noticed in the editor was the syntax highlighting indicating the presence of nested functions. At a glance, it seems like the variables returned by the whos() are only those that will be defined at some point in the scope of the base function.
You can recreate this with a simpler example:
function testcode
asdf = 1;
function testing
ghfj = 2;
end
end
If you set a breakpoint on the first line and run a whos(), you get
Name Size Bytes Class Attributes
ans 0x0 0 (unassigned)
asdf 0x0 0 (unassigned)
I couldn't seem to find anything explaining this behavior in the documentation for nested functions or related topics. I am not a computer scientist and my programming knowledge is limited to MATLAB and a very small sprinkling of Python. Can anybody explain what is going on? Does it have something to do with how MATLAB compiles the code at run time?
The workspace of a function with nested function is protected. When the function is called, Matlab has to analyze the code to determine which variables are in scope at what part of the function. Remember, variables that are declared in the main function and that are used in a nested function are passed by reference, and can be modified within the nested function even if not explicitly declared as input or output.
To avoid messing up any of the nested functions, and possibly to help speed things up, Matlab does not allow assigning any additional variables to the workspace of that function. For example, if you stop the execution of the code at line 1, and then try assigning a value to a new variable klmn, Matlab will throw an error. This can be a bit frustrating for debugging, but you can always assign ans, fortunately.

Can I view persisten variables in Matlab?

I have a problem that I'm having a hard time even framing for this question's title.
I have a library that calculates the properties of refrigerants. For example, you give pressure and enthalpy, and it tells you the temperature. That library is coded in Fortran with a mex file to interface with Matlab. Now, I am 100% sure that library is thoroughly debugged (it was coded by people much smarter than me, and has been used for almost a decade). The problem is definitely in how I call it.
And that problem is this. I call the library from a StartFcn callback (a .m script file) in a subsystem of a simulink model. The first time I run this model, it runs perfectly. The values I'm sedning to the function are therefore correct. The second time I run it, however, it crashes. The inputs both times are exactly the same.
Also, if I do a clear all between the two runs, then there is no crash. But if I do only clearvars or clear, I still get a crash. When I debug and look at the variables being passed in the function call, they are valid and the same both times.
Does someone have any experience with this, or can advise me on what I might be doing wrong? Is there something persisting within the function call that only clear all can remove and not clear? Save My Soul!
Yes, persistent variables can be declared by the persistent keyword.
If you want to clear only those, try
clear StartFcn
to clear all variables of the function StartFcn. A quote from the documentation:
If name is a function name, then clear name reinitializes any persistent variables in the function.
A quick thing to try would be clear mex inbetween simulations - this should clear all the mex code from matlab.
Other questions to think about..
Can you call the fortran interface directly from the matlab command line two times in a row?
I believe that using a m-file sfunction to call fortran in simulink is quite inefficient. Possibly consider writing your own fortran or C sfunction to interface to the code and compile in directly?
in case you're using LoadLibrary to load fortran code compiled into a dll, are you calling FreeLibrary in the mdlTerminate function?
Hope some of this helps.
I would try to put a clear all inside the function that you are calling in the StartFcn Callback.
So let's say your function is:
function [out] = nameoffunction(a,b,c)
%do calculation with a,b,c
d = a + b + c;
%output out
out = d;
assignin('base','out',d)
clear all
And you can call the function:
nameoffunction(a,b,c)
Let me know if it changes something. If this works, you could try other clear command but inside the function.

Simulink difference between load_system and open_system

I have a Simulink model that calls a script in the InitFcn of the Model callbacks. This script initializes a bunch of variables in the base workspace so that they can be used by the Simulink model. When using Classes, I found that using the load_system function will make Matlab crash and the open_system function will work just fine.
Here the Class:
classdef simulinkModel
properties
model = '';
end
methods
function obj = simulinkModel(modelName)
obj.model = modelName;
end
function openModel(obj)
% Make sure any previously open model are closed, and open the model.
if bdIsLoaded(obj.model)
obj.closeModel()
end
%load_system(obj.model) % Matlab crash
open_system(obj.model) % Matlab run the model correctly
end
function closeModel(obj)
close_system(obj.model, 0)
end
function runModel(obj)
sim(obj.model)
end
end
end
And in the command window:
objModel = simulinkModel('test');
objModel.openModel
objModel.runModel
So how comes it crashs with the load_system vs the open_system? Is there something that the open_system function do with the base workspace that the load_system function doesn't do?
EDIT
I decided to try running simple commands outside of the class to see if the problem is elsewhere. So typing in the command window:
load_system('test')
sim('test')
When executing this in the command window, Matlab will also crash. So I'm starting to wonder if the model callbacks are not executed when the load_system function is called.
I can confirm there is indeed very different behaviour between load_system and open_system. I am currently debugging a weird problem under 2015b to be, and I just realized the LoadFcn callback of my simulink models is not called when I use load_system, but is is called properly when I use open_system. I don't know that this is documented anywhere. I find this callback name misleading if it is not called when you "load" the system !!! If I find more info, I will post back on this thread.