I'm trying to understand this function and convert it to ctypes:
15 XDisplay* GetXDisplay() {
16 static XDisplay* display = NULL;
17 if (!display)
18 display = OpenNewXDisplay();
19 return display;
20 }
We see here if(!display) then do display = OpenNewXDisplay(); but what confuses me is the guy defines on the line above it that display is NULL (static XDisplay* display = NULL;) so why on earth the need for the if, if he just set it to null? Is display a global variable somehow?
display is a static variable.
For a static variable, initialisation only happens once, not every time the function is entered. This is just basic C (also basic C++, or basic Objective-C).
So this code is just a primitive way to create a singleton object.
As the others mentioned before display is a static variable.
The static storage class instructs the compiler to keep a local
variable in existence during the life-time of the program instead of
creating and destroying it each time it comes into and goes out of
scope. Therefore, making local variables static allows them to
maintain their values between function calls.
Source: http://www.tutorialspoint.com/cprogramming/c_storage_classes.htm
You should read more about whats static word means:
http://en.wikipedia.org/wiki/Static_variable
basicly it means that the variable will be defined only once. which means that on the next time the function will be called the previous value of the variable will be stay.
So its not quite a global variable since its has the scope of a regular variable but keeps its value over function calls.
Related
I am working on microntroller RZA1, with KPIT GNUARM 16 toolchain, in e2 studio. I am not an expert on the subject, so I'll try to explain the problem the best that I can. The issue is related to a structure mainwindow, defined in my code, which contains important features of the graphical interface:
typedef struct
{
page_t pages[MAXNUMPAGE];
logger_t storico;
messagges_t messaggio;
graph_t grafico;
} mainwindow_t;
In the main() function I declare a local instance of this struct, as it contains a while(1) loop, which is used to refresh the GUI application in case of user interaction (i.e pushbutton clicked). The problem that I have encountered is that there's a difference in the way program executes in case the instance of mainwindow_t is declared with or without static keyword. For instance,
main()
{
static mainwindow_t mainwindow;
....
init_pages(mainwindow.pages);
while(1)
{
page_update(mainwindow.pages);
}
}
works perfectly well, whereas with only mainwindow_t mainwindow; it seems that the changes made in the function init_pages() had no effect: entire content of the array page[MAXNUMPAGE] is uninitialized.
Therefore, my question is: should there be any functional difference between non-static local and static local declaration of an array inside a function, if that function basically never returns ?
The problem has nothing to do with whether the variable lives on the stack or not. It has to do with initialization.
Variables with static storage duration, i.e. file-scope variables or local variables with the static keyword, are implicitly initialized so that (loosely speaking) all variables with arithmetic type are initialized to 0 and all pointer variables are initialized to NULL.
In contrast, variables with automatic storage duration, i.e. variables declared inside of a function, are not initialized if there is no explicit initializer and its value is indeterminate.
While you didn't show your initialization function, it apparently doesn't set all fields in mainwindow.pages and depends on the other fields being zero-initialized. When mainwindow is declared non-static, this results in your program reading some indeterminate fields which causes undefined behavior, which explains why the problem mysteriously disappears when you attempt to trim down the code.
Adding an initializer to mainwindow addresses this issue by setting any fields explicitly listed, while applying the static object initialization rules to any remaining fields not explicitly initialized.
In a implementation for a real time embedded device, I have a status register variable for each channel (let's blindly assume my embedded device have multiple channels and some work has to be done for each of them).
So here's how the status variable is currently declared:
struct channel_status status[NCHANNELS];
Matter of performance, it is better to use an intermediate global variable that is the copy of the status variable for the selected channel.
Example:
struct channel_status status_shadow;
void some_work() {
for(channel = 0; channel < NCHANNELS; channel++) {
status_shadow = status[channel];
foo(); // Function that use the status_shadow as global
bar(); // "
baz(); // "
status[channel] = status_shadow;
}
Am I not discussing the implementation neither the possibility to use a pointer instead of a variable. My question is related to the name of the intermediate variable.
I chose status_shadow because I think I am doing some kind of shadowing.
Is there a better/more accurate technical name for such intermediate variable ?
Implementation considerations:
The reason why I decided to use this intermediate variable is because it is too resource consuming to pass either the channel pointer i or the status variable to each function foo, bar, baz, ... In terms of performance avoiding stack push/pop can save some precious time in real-time applications.
You are not technically shadowing; you would have to define a variable of the same name to shadow it. Moreover, shadowing is generally frowned upon because careless use could lead to easy confusion.
What you are doing is taking the current item for your cycle, so a suited name could be current_status or cur_status. If you used it as a parameter, so the name would be only contained into the for(), it could have been current or cur_item as well.
Another idea could be temp_channel_status, implying that the value is not to be considered fixed albeit the variable is global.
I would like a name such as work_status or status_copy.
You could use status_local, or status_local_copy.
This actually is a Question about the Tool ASCET, I don't have enough rep to create this Tag so I used the tag for the language that runs below.
I want to create a class as a process local for holding variables that are used in sub functions of a Module.
What is it that I need to do so that this varibale is correctly initialized each time the process starts anew? because if i simply use the variable I get the error:
ERROR(MMdl821): read access to method local variable "locvar_1" prior to initialization of reference
I dont want locvar_1 to be a reference at all, I only need the reference for passing it to the sub-functions.
I need this Solution for the Block-Diagramm mode.
I have written a Simulink S-function (Level 2) in C. The resulting block has one output and one parameter. This parameter is stored in a variable, which is defined at file scope, right after setting up the block:
#define NUM_PARAMS 1
#define NUM_INPORTS 0
#define NUM_OUTPORTS 1
unsigned short int MASK_INDEX;
I assign it within mdlInitializeSizes, and do some operations on its value:
static void mdlInitializeSizes(SimStruct *S) {
// Check Parameters
ssSetNumSFcnParams(S, NUM_PARAMS);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));
(...) operations
}
My problem is, that the variable MASK_INDEX seems to be global, and shared among all blocks of the same type. Therefore, it holds the same value for all blocks.
As a workaround, I reload it every time, and re-do the operations, for example:
static void mdlOutputs(SimStruct *S, int_T tid) {
MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));
(...) operations
}
How can I get a true "local variable", so that I don't have to repeat all this every time?
You haven't mentioned where you've declared MASK_INDEX, but from your description it sounds like it's at file scope. If so, then yes, this variable will be shared across all instances. This is not isolated to S-Functions in any way, it's how shared libraries on most, if not all, platforms behave. A single instance of the shared library will be loaded by an application, in this case MATLAB; consequently there is only one copy of global variables.
The easiest option is to use ssGetSFcnParam every time you want to access the parameter. If you dig into those S-Function macros, they're simply accessing fields of the SimStruct, so it's unlikely repeated access will result in performance degradation. I've even seen macros being used to wrap common use cases such as the one you have.
If you really want to go about caching the dialog parameter, the easiest is probably to use ssSetUserData. Declare a struct containing a MASK_INDEX member (you don't have to use a struct but this approach is more extensible). Dynamically allocate an instance using mxMalloc within mdlStart and assign it to the block's user data. Make sure you set SS_OPTION_CALL_TERMINATE_ON_EXIT in the ssSetOptions call in mdlInitializeSizes. Then define the mdlTerminate function within which you'll access the allocated struct using ssGetUserData and mxFree it. Now you can access the struct members within mdlOutputs using ssGetUserData.
There are other, more advanced options as well, such as work vectors, probably a PWork vector.
Another option, if your parameter is tunable, is using runtime parameters, which let you cache, and optionally transform, a block's dialog parameters.
In your case, I'd just stick with using ssGetSFcnParam every time within mdlOutputs.
This is a sort of followup to my previous question about nested registered C functions found here:
Trying to call a function in Lua with nested tables
The previous question gave me the answer to adding a nested function like this:
dog.beagle.fetch()
I also would like to have variables at that level like:
dog.beagle.name
dog.beagle.microchipID
I want this string and number to be allocated in C and accessible by Lua. So, in C code, the variables might be defined as:
int microchipIDNumber;
char dogname[500];
The C variables need to be updated by assignments in Lua and its value needs to be retrieved by Lua when it is on the right of the equal sign. I have tried the __index and __newindex metamethod concept but everything I try seems to break down when I have 2 dots in the Lua path to the variable. I know I am probably making it more complicated with the 2 dots, but it makes the organization much easier to read in the Lua code. I also need to get an event for the assignment because I need to spin up some hardware when the microchipIDNumber value changes. I assume I can do this through the __newindex while I am setting the value.
Any ideas on how you would code the metatables and methods to accomplish the nesting? Could it be because my previous function declarations are confusing Lua?
The colon operator (:) in Lua is used only for functions. Consider the following example:
meta = {}
meta["__index"] = function(n,m) print(n) print(m) return m end
object = {}
setmetatable(object,meta)
print(object.foo)
The index function will simply print the two arguments it is passed and return the second one (which we will also print, because just doing object.foo is a syntax error). The output is going to be table: 0x153e6d0 foo foo with new lines. So __index gets the object in which we're looking up the variable and it's name. Now, if we replace object.foo with object:foo we get this:
input:5: function arguments expected near ')'
This is the because : in object:foo is syntactic sugar for object.foo(object), so Lua expects that you will provide arguments for a function call. If we did provide arguments (object:foo("bar")) we get this:
table: 0x222b3b0
foo
input:5: attempt to call method 'foo' (a string value)
So our __index function still gets called, but it is not passed the argument - Lua simply attemps to call the return value. So don't use : for members.
With that out of the way, let's look at how you can sync variables between Lua and C. This is actually quite involved and there are different ways to do it. One solution would be to use a combination of __index and __newindex. If you have a beagle structure in C, I'd recommend making these C functions and pushing them into the metatable of a Lua table as C-closures with a pointer to your C struct as an upvalue. Look at this for some info on lua_pushcclosure and this on closures in Lua in general.
If you don't have a single structure you can reference, it gets a lot more complicated, since you'll have to somehow store pairs variableName-variableLocation on the C side and know what type each is. You could maintain such a list in the actual Lua table, so dog.beagle would be a map of variable name to one or two something's. There a couple of options for this 'something'. First - one light user data (ie - a C pointer), but then you'll have the issue of figuring out what that is pointing to, so that you know what Lua type to push in for __index and what to pop out for __newindex . The other option is to push two functions/closures. You can make a C function for each type you'll have to handle (number, string, table, etc) and push the appropriate one for each variable, or make a uber-closure that takes a parameter what type it's being given and then just vary the up-values you push it with. In this case the __index and __newindex functions will simply lookup the appropriate function for a given variable name and call it, so it would be probably easiest to implement it in Lua.
In the case of two functions your dog.beagle might look something like this (not actual Lua syntax):
dog.beagle = {
__metatable = {
__index = function(table,key)
local getFunc = rawget(table,key).get
return getFunc(table,key)
end
__newindex = function(table,key,value)
local setFunc = rawget(table,key).set
setFunc(table,key,value)
end
}
"color" = {
"set" = *C function for setting color or closure with an upvalue to tell it's given a color*,
"get" = *C function for getting color or closure with an upvalue to tell it to return a color*
}
}
Notes about the above: 1.Don't set an object's __metatable field directly - it's used to hide the real metatable. Use setmetatable(object,metatable). 2. Notice the usage of rawget. We need it because otherwise trying to get a field of the object from within __index would be an infinite recursion. 3. You'll have to do a bit more error checking in the event rawget(table,key) returns nil, or if what it returns does not have get/set members.