how can i control a global variable in "C" file which is shared between different functions and are called using code.ceval

Assume the following C code. i just tried to generalise the code as my i need.
/* C Code*/
//declaration of global variable
int flag = 0;
//function 1 definition
temp_func1 ()
{
flag = 1
}
//Function 2 definition
temp_func2(int *ptr)
{
if (flag == 1)
{
*ptr = 10;
}
else
{
*ptr=0;
}
}
//Matlab function
global temp_act;
coder.ceal('temp_func1');
coder.ceal('temp_func2',coder.ref(temp_act));
The abvoe matlab function is always returning 0 which means that the global variable flag updated in a function temp_func1 is not getting reflected in temp_func2. i confirmed this by removing the condition (flag==1) from the C code and successful in getting the value 10 from the matlab function. Appreciating your support.

Answers (1)

Hi,
As per my understanding, you want to manage a global variable when interfacing between MATLAB and C code using the "coder.ceval" function.
One of the possible ways to do this is, since MATLAB may not directly manage the state of C global variables, providing accessor functions in C to explicitly get and set the value of the flag will avoid potential issues with the global variable's state not being recognized across different function calls. In MATLAB, you would then use "coder.ceval" to call these accessor functions:
% MATLAB function
global temp_act;
coder.ceval('temp_func1');
coder.ceval('set_flag', 1); % Explicitly set the flag to 1
coder.ceval('temp_func2', coder.ref(temp_act));
Another approach to address this is to use "persistent memory" in MATLAB to store and manage the state of the global variable. This method avoids direct manipulation of the C global variable and encapsulates the state within the MATLAB environment and uses pass-by-reference to share the state with the C functions. Please refer to the below modifications required in the C and MATLAB code for using this approach.
"C code" modification: Remove the global variable "flag" from the C code and modify the functions to accept a pointer to the flag as an argument.
/* C Code */
// Function 1 definition
void temp_func1(int *flag) {
*flag = 1;
}
// Function 2 definition
void temp_func2(int *flag, int *ptr) {
if (*flag == 1) {
*ptr = 10;
} else {
*ptr = 0;
}
}
"MATLAB Code" modification: Use a "persistent" variable in MATLAB to hold the state of the flag and pass it to the C functions as needed.
% MATLAB function
persistent flag;
if isempty(flag)
flag = 0; % Initialize the persistent variable
end
temp_act = 0; % Initialize the output variable
% Call the C functions with the persistent variable
coder.ceval('temp_func1', coder.ref(flag));
coder.ceval('temp_func2', coder.ref(flag), coder.ref(temp_act));
% Now temp_act should have the correct value based on the state of flag
Please refer to the MATLAB documentation for further understanding:
Hope this helps!

6 Comments

Thanks for your response !!
To be precise, i am testing a model which calls a C function and update some variables. For testing purpose, i just stubbed the C funciton so that i can read out the values and ensure the writing is working fine. Here, i can stub the definition of the C function but i cannot alter the parameters of the C-Function. So sending the flag as a parameter is something that i need to modify the C function parameter which i cannot do in my case. Do you have any other option to handle this?
Given the constraints where the C function parameters cannot be modified, another possible solution would be to ensure that the global variable "flag" is correctly linked between the C code and the MATLAB environment. Here's an alternative approach that might work within these constraints:
Instead of directly embedding the C code in the MATLAB environment, you could compile the C code into a shared library (DLL on Windows or SO on Linux/Mac). MATLAB can then load this shared library and call the functions within it, which will ensure that the global variable "flag" retains its state across function calls because the state is maintained within the shared library. The possible workaround for this is:
  • You will need to create a header file (temp_funcs.h) that MATLAB can use to interface with the shared library.
  • The shared library approach ensures that the global variable "flag" is only one instance within the shared library's memory space.
  • This method requires that the MATLAB environment has the necessary permissions to load shared libraries.
By using a shared library, you can avoid changing the C function's parameters and maintain the global variable's state across multiple function calls from MATLAB.
Please refer to the MATLAB Documentation for further understanding:
Hope this helps!
i tried the following methods and failed in all of them,
1) tried for creation of linked library but the compiler sdk only allows me to convert the m-script in to linked library and not a C code in to a linked library. Then i tried converting the C code in to mex but it is failed due to non-presence of the mexfunction which i dont know how to create for multifunction C file
2) tried creating a static library (archive file) and tried linking it but got an error that the library is not compatible with x86 since i created the static library with power-pc environment.
3) i do have a dynamic library already created for the C file in powerpc environment, which i tried loading using loadlibrary option and got error that it is not a valid win-32 application and i dont know how to use the loadlibrary for the shared objects created in the unix environment.
appreciating your response!!
Hi Suthakar,
As you mentioned in the first point that mex file could not be created due to absence of mexFunction, to resolve this you might create a wrapper C file that defines the mexFunction. This function is the entry point for MEX files and allows MATLAB to call C/C++ functions. The wrapper will translate MATLAB inputs into the format expected by the original C functions and vice versa.
You can refer to the following example for this:
#include "mex.h"
// Assume we have two C functions we want to call
extern void temp_func1();
extern void temp_func2(int *ptr);
// MEX function wrapper
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
// Check for proper number of arguments, etc.
// Call the C functions
temp_func1();
// Assume temp_func2 modifies some global state that affects its output
int temp_act;
temp_func2(&temp_act);
// Create MATLAB output
plhs[0] = mxCreateDoubleScalar((double)temp_act);
}
Thanks!
Thanks for your response.
i did the following,
1) i have included the mexfunction in C file and successfully generated the mex file followed by the linked library created in the form of .dll.
2) The dll is included using the SimUserLibraries option and it is now included in the model configuration parameter.
3) the model will still try to invoke the C-function using coder.ceval. i did try to compile the model and got an issue that the model is unable find the definition of the C-function.
4) how can i check the presence of the C-function in the created mex or dll ? this is just to double check the conversion.
is there anything more to be taken care?
appreciating your support!!
Hi,
To solve this you need to ensure that the MEX file and the DLL are correctly being referenced and that the C-function is properly exported and accessible.
Check the presence of C-function in a MEX File
Use "mex" command of MATLAB : If you have compiled the C code into a MEX file, you can test the MEX function directly in MATLAB by calling it like any other MATLAB function. If the MEX function works as expected in MATLAB, it confirms the presence and accessibility of the C-function.
Check the presence of C-function in a DLL
Use Dependency Walker : On Windows, Dependency Walker (depends.exe) is a free utility that scans any 32-bit or 64-bit Windows module (DLL, EXE, etc.) and builds a hierarchical tree diagram of all dependent modules. You can open the DLL with Dependency Walker to see if the C-function is listed as an exported function.
Ensure that the DLL is correctly referenced
Also, please ensure that the DLL is in the sytem path, or the path to the DLL is specified in MATLAB using the "addpath" function or by configuring it in the model settings under the "SimUserLibraries" option.
Hope it helps!

Sign in to comment.

Categories

Find more on MATLAB Compiler SDK in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!