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.
Related
Consider a codebase with this file structure:
myScript.m (Script)
+modA/
fn.m (Function)
+modB/
fn.m (Function)
myScript.m must choose which of modA.fn or modB.fn to call at runtime using the outcome of a string str_moduleName.
Is there a way to avoid calling feval([str_moduleName,'.fn']) ?
I haven't tried this, but I guess you could build a struct with function handles:
S.modA = #modA.fn
S.modB = #modB.fn
Then you can call the function using the value of str_moduleName as follows:
S.(str_moduleName)()
I have code that produced a circular build error, and I looked up the error. This page gives a similar but smaller example of what's in my .mli file: https://ocaml.org/learn/tutorials/ocamlbuild/New_kinds_of_build_errors.html
Essentially the problem is that my file is both defining a type and defining functions that use arguments and return values of that same type. However, that's exactly what I want my program to do. My type is not private, it's declared explicitly in the .mli file:
type state = {
current_pos : int*int;
contents : int*int list;
}
val update_state : state -> state
It seems to me reasonable to want to build a module that defines a type and then to share that type with other files, but it seems like the circular build error will always prevent that. Is there some "more proper" way of doing this sharing?
There's nothing at all wrong with the code you posted. It compiles fine. So the problem is in your .ml file.
The page you point to shows code that is incorrect. The only point being made is that you'll get a different error if you use ocamlbuild than you would if you just compile the file directly.
The key point is that you should not use the name of a module inside the definition of the module.
Instead of this (in a.ml):
type t = int
let x : A.t = 14
You should have this:
type t = int
let x: t = 14
If your code is really like this example, you just need to remove the module names inside the .ml file.
As you say, what you want to do is by far the most common use of a module.
I meet a problem in the s function builder, I have to use a temp structure variable to transport the inputs to the extended C function.
Background: csolve function is a quadratic programming solver generated by CVXGEN for my QP problem, and I have tested the function in level-2 matlab s-fun. Now I want to use s function builder to genetate the TLC file that support the embedded code generate.
My Problem:
1) I have to use a temp structure variable 'params' to the inputs to csolve function in the outputs panel, could you please help me to solve this problem?
2) I find that in cvxgen folder contains a header file contains 'tic' and 'toc' function, how to use these functions in s function builder?
params.Aeq=Aeq;
params.beq=beq;
params.Aineq=Aineq;
params.bineq=bineq;
params.Smat=Smat;
params.Wmat=Wmat;
params.alpha=alpha;
[vars, status] = csolve(params)
y0=vars.x;
converge=status.converge;
for the attached files please see here
First some background information that you should know:
Matlab and C work completely differently and use different kinds of data types. To call C code from Matlab, so called "mex-functions" are generated. Matlab uses a special data type named mxArray to exchange data between Matlab and these "mex-functions", which are written in C.
In the C program an element (for example a variable) of the type mxArray represents a Matlab value of any data type. Matlab provides some functions (like mxGetData()) to access the actual data of the Matlab data element from the C function: There is some function for checking if the mxArray represents a floating-point value or a string. Another function allows you to convert the value from mxArray to double if the element has a floating-point value.
[vars, status] = csolve(params)
This means you want to call a "mex-function" from an "S-function".
Theoretically, this is possible but it is not as easy as you think:
First of all, the entry point of both types of functions is named mexFunction() in the C code. This means you cannot simply combine the C codes of both functions because in this case you would have two functions with the same name (mexFunction) in your S-function.
You might call the function mexCallMATLAB; however Mathworks writes that this function should not be called from S-functions.
The other possibility would be loading the mex-function using DLL functions (in Windows: LoadLibrary, GetProcAddress, FreeLibrary) and call the function mexFunction() of the mex-function using a function pointer.
However, in this case you have to convert all C data types to mxArray data and the data returned from the mex-function must be converted back ...
... a TLC file that is needed in ... embedded coder
The functions that access data of the mxArray type are only available when Matlab is running.
If you generate code that shall be executable outside Matlab, you cannot use mxArray and therefore you cannot call mex-functions.
The file csolve.c defines four structure variables:
Vars vars;
Params params;
Workspace work;
Settings settings;
And what the file actually does is the following:
Read the structure params (mxArray data type), convert these content to C data types and write the data into the four structure variables above
Call the following code:
steps = solve();
for (i = 0; i < extra_solves; i++)
solve();
The function solve() is defined in the other .c files in the project.
Take the values from the four structure variables and the value step returned by solve() and convert the data to mxArray.
Return the result as [vars, status]
You can define the four variables in your S-function code, fill these structures the same way the file csolve.c does it, call the solve() function as it is shown above and read the data of vars and status directly from the four variables.
You remove csolve.c from your project and add the other .c files of your mex-function to the S-function.
I'm using Doxygen to document a Fortran code and I have variables declared such as:
REAL(KIND=8), PARAMETER :: myParam = 1.0_8
but Doxygen gets confused and seems to think REAL is a function and throws:
warning: documented function `real' was not declared or defined.
I have OPTIMIZE_FOR_FORTRAN set to YES so that's not the issue.
Is there a way to rectify this without having to wrap some pre-processor guard around my variables to declare them as REAL without the KIND parameter when building documentation?
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.