The mcc compiler "Depfun error" when building dll with .NET-dependencies and Enumerations That Encapsulate Data - matlab

I ran into problems in MATLAB R2010b when creating a DLL that uses .NET-integration and enumerations with encapsulate data.
Example:
There is a .NET Assembly which is used in MATLAB, let's call it "MyAssembly" (MyAssembly.dll).
There Matlab Enumerations Class "OpenMode"
classdef OpenMode
methods
function obj = OpenMode(netType)
obj.Net = netType;
end
end
properties
Net
end
enumeration
ReadOnly (MyAssembly.OpenMode.ReadOnly)
ReadWrite (MyAssembly.OpenMode.ReadWrite)
end
end
This class uses the .NET enumeration: "MyAssembly.OpenMode"
In such a way to access the .NET-enumeration via Matlab-enumeration (In my case it is necessary for cast types):
netElem = OpenMode.ReadOnly.Net;
cls = class(netElem)
cls =
MyAssembly.OpenMode
The Matlab-Function, that should be exported:
function retVal = MyFunction(inputs)
NET.addAssembly('MyAssembly.dll');
flag = OpenMode.ReadOnly;
netFlag = flag.Net;
% Some code...
end
Add .NET Assembly in Matlab (checking)
NET.addAssembly('MyAssembly.dll')
Try to compile the Dll:
mcc -B csharedlib:MyLib MyFunction
...and get the error:
Depfun error: 'Undefined variable "MyAssembly" or class "MyAssembly.OpenMode.ReadOnly".'
??? Error using ==> mcc
Error executing mcc, return status = 1 (0x1).
The mcc compiler does not detect in code enumeration that "MyAssembly" exists, but here is a function will be compiled successfully:
function retVal = MyFunction(inputs)
netflag = MyAssembly.OpenMode.ReadOnly;
% Some code...
end
If you have faced similar problems in MATLAB and found a solution, please tell me what to do.
Thanks!
Regards,
iroln

I seem to find solutions to these problems. It's not very elegant, but it works.
The mcc compiler has the option "-a filename". This option enables you to add the specified files for CTF archive. You want to add all the files that defines the enumeration using .NET Assemblies:
Example for my case:
mcc -B csharedlib:MyLib MyFunction -a OpenMode
...or in general:
mcc -B csharedlib:MyLib MyFunction -a projectdir/*.m
I have automated this with a build-script.
This is so far the only solution that works.

Related

How to load multiple modules implementing the same behaviour

I do not understand how is one supposed to use multiple modules that each implement the same behaviour since i get this error at compile time:
Function is already imported from
In my case i have two modules implementing gen_event behaviour and i am trying to import them in a third module.
I get the error message whenever i am trying to compile this code:
-module(mgr).
-import(h1,[init/1]). // implements gen_event
-import(h2,[init/1]). // implements gen_event
You can't do that. Import is a simple trick to avoid to write the complete "definition" of a function. It does nothing but just says to the compiler : when you see init(P) in this module, replace with h1:init(P).
Thus it is not possible to import several function with the same name/arity.
For short names, I do not see any benefit to use import.
If you are using module:function with long names, and you want to shorten the lines in the code, it is possible to use macros instead, and there are no limitation (but also few chance that the function name are the same :o):
-define(Func1(Var1,...,VarN), module1:func(Var1,...,VarN)).
-define(Func2(Var1,...,VarN), module2:func(Var1,...,VarN)).
...
?Func1(A1,...,AN);
...
?Func2(B1,...,BN);
Edit
The next example illustrates how it works, first I create the module mod1 as follow:
-module (mod1).
-export ([test/1]).
test(P) ->
case P of
1 -> ok;
2 -> mod2:test()
end.
and I test it in the shell:
1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.
mod2 is created as:
-module (mod2).
-export ([test/0]).
test() ->
io:format("now it works~n").
continue in the shell:
4> c(mod2).
{ok,mod2}
5> mod1:test(1).
ok
6> mod1:test(2).
now it works
ok
7>
As you can see, it is not necessary to modify mod1, but only to create and compile mod2 (note that it would be the same if mod2 already exists but the function test/0 is not exported).
If you want to verify that your code is not using undefined function, you can use external tools. As I am using rebar3 to manage my projects, I use the command rebar3 xref to perform this check. Note that calling an undefined function is a simple warning, it is meaningful in the context of application upgrading. This verification is not bullet proof: it is done at build time, this does not guarantee that the modules yo need will be present, with the right version on a production system: it opens a lot more interesting questions about versioning, code loading...

Matlab Coder using boolean_T

I'm trying to generate C code for a simple function Matlab funciton:
function[] = myfunc()
%#codegen
fprintf('Executing myfun\n');
fid = fopen('file_created_by_myfun.txt','w');
fwrite(fid,'This is written by myfun upon execution');
fclose(fid);
end
However, in the generated code a variable type boolean_T is used but not declared anywhere. It seems to me that no header with its declaration was included.
The script to generate the code is:
config_obj = coder.config('exe');
config_obj.GenCodeOnly = 'on';
codegen -config config_obj myfun
By calling make with a custom makefile, I get the following error messages:
error: unknown type name 'boolean_T'
error: 'false' undeclared (first use in this function)
error: 'true' undeclared (first use in this function)
I can ask for single file and add custom code with:
config_obj = coder.FilePArtitioningMethod('SingleFile');
config_obj.CustomSourceCode = ['typedef unsigned int boolean_T;',newline,...
'#define true 1U',newline,...
'#define false 0U'];
This will allow me to compile the code properly, but it's a crappy solution, since I don't want to generate a single file, and the added source is not included in every file as needed.
Is there any way I can avoid having the boolean_T type being used? Or there some directive I should have used but I'm missing?
boolean_T and possibly other types like int_T are defined in header files that are not generated, but shipped with MATLAB. Usually the definitions are in tmwtypes.h which you can find in /extern/include. The generated makefile includes a path to this in the list of include directories as an option to the compiler. If you are not using the generated makefile you would need to add the paths to these headers manually to your compiler options.

Matlab: Can't run class method as a normal function?

I've defined a class cMyClass, with a method as a separate m-file SomeMethod.m within the #cMyClass folder. I can invoke SomeMethod as a normal function (rather than a method) as long as it is copied outside of folder #cMyClass. When the current working directory is the folder #cMyClass, however, SomeMethod is not recognized (I supply an empty struct as the argument in place of the expected host object). I've tried clear classes and rehash after changing folders to #cMyClass, but they don't help.
This takes away a convenience in tactical testing and troubleshooting. I'm wondering if such a behaviour is really hard coded into Matlab, or is there something that I'm missing? The test code is as follows.
The class definition #cMyClass/cMyClass.m:
% #cMyClass/cMyClass.m
% --------------------
classdef cMyClass < handle
methods
SomeMethod(o)
end % methods
end % classdef
The method definition in #cMyClass/SomeMethod.m:
% #cMyClass/SomeMethod.m
% ----------------------
function SomeMethod(o)
'Hello world'
end % function
I succeeded in the conventional invocation of SomeMethod as a class method:
>> oMyClass = cMyClass
oMyClass =
cMyClass with no properties.
>> oMyClass.SomeMethod
ans =
Hello world
Unfortunately, I failed to invoke SomeMethod as a normal function from with folder #cMyClass:
>> cd #cMyClass
>> clear all; clear classes
>> rehash
>> o=struct
o =
struct with no fields.
>> SomeMethod(o)
Undefined function or variable 'SomeMethod'.
However, I succeeded in invoking SomeMethod from outside of #cMyClass. I used a shell to copy SomeMethod.m up one level to #cMyClass/.. (in POSIX path notation), then executed:
>> cd .. % Go to #cMyClass/..
>> clear all; clear classes
>> rehash
>> o=struct
o =
struct with no fields.
>> SomeMethod(o)
ans =
Hello world
Another illustration of success when the function doesn't reside in a folders starting with # is to copy #cMyClass to not_cMyClass and execute:
>> cd not_cMyClass
> clear all; clear classes
>> rehash
>> o=struct
o =
struct with no fields.
>> SomeMethod(o)
ans =
Hello world
The puzzling thing is that when Matlab's current working directory is #cMyClass, cMyClass is not recognized as a class and so SomeMethod.m should not be interpretted as a method file:
>> cd ..\#cMyClass\
>> clear all
>> clear classes
>> rehash
>> c=cMyClass
Undefined function or variable 'cMyClass'.
In other words, one would expect SomeMethod.m to be interpretted as a normal function file, in the same way as it is when it resides in not_cMyClass and #cMyClass/.. above.
In lieu of a solution, I have to maintain a copy of SomeMethod.m outside of folder #cMyClass, and keep manually keep the two copies synchronized. Human error becomes a hazard.
Please note that since I am using Cygwin on a Microsoft Windows machine, both / and \ get used as a path separator, depending on the context.
Note that creating a virtual copy by using unix's ln -s or by creating a Microsoft Windows shortcut in #cMyClass/.. does not work. Matlab will not recognize these as m-files.
This is expected behavior. MATLAB dispatches function calls based on the types of the arguments. A function cMyClass/func will be called for func(obj) if obj is of type cMyClass. If not, a different func will be called. You will get an error if func is not defined for whatever class obj is, and there is no func outside of a class directory.
There is no way to call #cMyClass/func.m using func({}) or some such syntax. If you want to be able to call this function with an empty object, you need to modify your class so that cMyClass (the class constructor) returns an empty object. Then you can do func(cMyClass).
The other alternative is to make func a static method. Then you can call it wuth cMyClass.func.
Do note that for troubleshooting and debugging, you can still set breakpoints and debug as you would any other function. I really don't see the need to call such a function with an illegal input...

Define Simple MATLAB Class

I am a Microsoft developer but trying to assist someone with some MATLAB code and design. I'm struggling to understand the syntax and usage of a class definition.
Code so far:
classdef Person
properties
Name
end
methods
function obj = Person(aName)
obj.Name = aName;
end
function ret = IsGraeme(obj)
if STRCMP( obj.Name , 'Graeme')
ret= 1;
else
ret= 0;
end
end
end
end
Now, I expect my usage to be similar to below:
graeme = Person('Graeme');
graeme.IsGraeme();
with the last line returning 1.
The first line of usage results in an error:
Too many inputs
The samples I have found on MATLAB seem to give you the classdef but not the usage.
I hope someone can help correct this simple example so that I can continue to build on it. (As mentioned, I am an experienced dev, just not in this language!).
UPDATE 1:
Using MATLAB 2013b.
Exact usage and resultant error below:
>> gt = Person('Graeme')
Error using Person
Too many input arguments.
The OP's solution ended up being running the clear command in MATLAB. In all likelihood, what happened is an old class definition was already stored in memory and for some reason was not automatically updated. Anyhow - an easy fix!
Just in case others who stumble on this question what an explanation of the simplest basics of class constructors...
In MATLAB, you can an instance of a class without a constructor function, you follow the approach shown here, summed up below:
>> gt = Person();
>> gt.Name = 'Graeme';
>> gt.IsGraeme();
The OP wanted to create a constructor so that he could assign values to the class object's properties at initialization. Just for clarity's sake, a constructor is:
a method having the same name as the class.
The below (modified to fit OP's use-case) code is essentially copied from here. The only difference here is that we first check whether an input value has been provided before attempting to assign a (potentially undefined) value to a property of the instantiated class object:
function gt = Person(aName)
if nargin > 0 % Check if more than 0 arguments are provided
gt.Name = aName; % Assign input argument to property
end
end
Now (as before), gt = Person('Graeme') will work as expected. This obviously assumes that the class is saved in a properly named M-file and that you've run clear to get rid of previous variable assignment mistakes.

use argument to system object in matlab code generation

I'm tring to use system object for my generated matlab code (.mex)
here is the function.
function [ ] = filereaderTest( videofile )
fileReader = vision.VideoFileReader(videofile);
while ~isDone(fileReader)
step(fileReader);
% do something
end
release(fileReader);
end
when I try codegen filereaderTest -args videofile , error occurs.
It says "fail to compute constant value for constructor arguement #1. To generate code, all argument for System Object constructor should be constant. ..."
To use VideoFileReader, must pass file name to its constructor.
So, here is my question: there is any way to use this function to any files? for example:
filereaderTest.mex(video1);
filereaderTest.mex(video2); % video1 and video2 are different
What you are trying to do is not possible. The documentation states clearly:
Set arguments to System objectâ„¢ constructors as compile-time constants.
(1)