Creating a global "null" struct for re-use in C program? - objective-c

Not sure what I'm doing wrong here. I have a struct that is used heavily through my program.
typedef struct _MyStruct {
// ... handful of non-trivial fields ...
} MyStruct;
I expect (read, intend) for lots of parts of the program to return one of these structs, but many of them should be able to return a "null" struct, which is a singleton/global. The exact use case is for the implementing function to say "I can't find what you asked me to return".
I assumed this would be a simple case of defining a variable in a header file, and initializing it in the .c file.
// MyStruct.h
// ... Snip ...
MyStruct NotFoundStruct;
-
// MyStruct.c
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
// etc etc
But the compiler complains that the initialization is not constant.
Since I don't care about what this global actually references in memory, I only care that everything uses the same global, I tried just removing the initialization and simply leaving the definition in the header.
But when I do this:
MyStruct thing = give_me_a_struct(some_input);
if (thing == NotFoundStruct) {
// ... do something special
}
Th compiler complains that the operands to the binary operator "==" (or "!=") are invalid.
How does one define such as globally re-usable (always the same memory address) struct?

This doesn't directly answer your question, but it won't fit in a comment...
If you have a function that may need to return something or return nothing, there are several options that are better than returning a "null struct" or "sentinel struct," especially since structs are not equality comparable in C.
One option is to return a pointer, so that you can actually return NULL to indicate that you are really returning nothing; this has the disadvantage of having significant memory management implications, namely who owns the pointer? and do you have to create an object on the heap that doesn't already exist on the heap to do this?
A better option is to take a pointer to a struct as an "out" parameter, use that pointer to store the actual result, then return an int status code indicating success or failure (or a bool if you have a C99 compiler). This would look something like:
int give_me_a_struct(MyStruct*);
MyStruct result;
if (give_me_a_struct(&result)) {
// yay! we got a result!
}
else {
// boo! we didn't get a result!
}
If give_me_a_struct returns zero, it indicates that it did not find the result and the result object was not populated. If it returns nonzero, it indicates that it did find the result and the result object was populated.

C doesn't allow global non-const assignments. So you must do this in a function:
void init() {
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
}
As for the comparison, C doesn't know how to apply a == operator to a struct. You can overload (redefine) the operator in C++, but not in C.
So to see if a return value is empty, your options are to
Have each function return a boolean value to indicate found or not, and return the struct's values via pointers through the argument list. (eg. bool found = give_me_a_struct(some_input, &thing);)
Return a pointer to a struct, which can be NULL if nothing exists. (eg. MyStruct* thing = give_me_a_struct(some_input);)
Add an additional field to the struct that indicates whether the object is valid.
The third option is the most generic for other cases, but requires more data to be stored. The best bet for your specific question is the first option.

// MyStruct.h
typedef struct _MyStruct {
// fields
} MyStruct;
extern MyStruct NotFoundStruct;
// MyStruct.c
#include "my_struct.h"
MyStruct NotFoundStruct = {0};
But since you can't use the == operator, you will have to find another way to distinguish it. One (not ideal) way is to have a bool flag reserved to indicate validity. That way, only that must be checked to determine if it's a valid instance.
But I think you should consider James's proposed solution instead

In the header:
// Structure definition then
extern MyStruct myStruct;
In the .c that contains global data
struct MyStruct myStruct
{
initialize field 1,
initialize field 2,
// etc...
};

Related

Is that an in or in/out parameter? Doxygen, C++

If a pointer is passed to a function for read only, then this pointer is an IN parameter.
If a pointer is passed to a function for read only, but this function makes a copy of the pointer to have access to it in module related functions for read only operations, this pointer is still IN.
If the function still uses the pointer as read only, but the other module related functions use the pointer for write operations, what does that make the pointer?
An IN parameter, but without const? An in/out parameter?
Example of what I mean:
class SteeringWheel {
public: float rotation;
public: SteeringWheel(void) {
this->rotation = 0.f;
}
};
class Car {
private: SteeringWheel *steeringWheel;
public:
/**
* #param[?] steeringWheel Is the steering wheel in or in/out?
*/
Car (SteeringWheel *steeringWheel) {
this->steeringWheel = steeringWheel;
}
/**
* #param[in] degree Steering amount in degrees.
*/
void steer(float degree)
{
this->steeringWheel->rotation += degree;
}
};
int main(int argc, char **argv)
{
SteeringWheel steeringWheel();
/* car() uses steeringWheel as read only. */
Car car(&steeringWheel);
/* steer() uses steeringWheel from car() to write. */
car.steer(50.f);
return 0;
}
I believe that the in and out specifiers do not exactly mean what you think. From the doxygen documentation of the param tag:
The \param command has an optional attribute, (dir), specifying the
direction of the parameter. Possible values are "[in]", "[in,out]",
and "[out]", note the [square] brackets in this description. When a
parameter is both input and output, [in,out] is used as attribute.
The direction of the parameter usually mean the following:
in: The parameter is injected into the function as input, but not written to.
out: The parameter is injected into the function, but not as input. Rather, it is written to by the function.
in, out: The parameter is injected into the function as input and is eventually written to by the function.
In your example:
/**
* #param[?] steeringWheel Is the steering wheel in or in/out?
*/
Car (SteeringWheel *steeringWheel) {
this->steeringWheel = steeringWheel;
}
I think the steeringWheel parameter is in because you inject it and use it in your method. However, you never write to it (i.e. to the parameter itself), so it is not out. In other words, you only use your method to inject an address to your function, nothing else. The same apply for your second method, where you inject the degree parameter, but never write to it.
To clarify a bit more on the meaning of in and out, here is an example of an out parameter:
/**
* #param[out] p_param We write to the parameter!
*/
void makeFour(int * p_param)
{
*p_param = 4; // Out because of this line!
}
Notice that we write a new value directly into the parameter. This is the meaning of out: information comes out of the method through the parameter. You can now write:
int main()
{
int myInt = 0;
std::cout << myInt; // prints 0.
makeFour(&myInt); // p_param == &myInt here.
std::cout << myInt; // prints 4: the method wrote directly
// in the parameter (out)!
return 0;
}
Hope this helps!
It is not easy to decide, but I would still mark your parameter as in,out (or out), as it is a pointer to a non-const object, and you may change the state of that outside object directly or indirectly later - as in your example.
Marking it in hides the detail that the pointed SteeringWheel object may change later upon usage of Car.
Also, it can puzzle users why an input only pointer parameter is not marked const.
Making it in,out may not be accurate completely, but is surely more error prone.
An alternative could be something like the following (a note regarding the lifetime of the SteeringWheel should come handy here anyway):
/**
* #param[in] steeringWheel Pointer to the SteeringWheel object.
* #warning The memory address of the pointed object is saved.
* It must outlive this object, and can change upon usage of this object.
*/
Car (SteeringWheel *steeringWheel) {
this->steeringWheel = steeringWheel;
}
But I would just probably stick with marking it in,out.
Specifying the direction of parameters in C++ may be complicated, and frankly speaking, I am not too much in favor of them, as having tokens for pointers, references, and the keyword for constness provide enough information in the signature on how a parameter may be used. Thus, marking it in the DoxyPress documentation is a bit redundant, not expressive enough (as your example shows), and may get out of sync with the implementation. Documenting parameter directions may play a bigger role in case of other languages that lack these additional constructs in function signatures.

I am about to use dlopen() to open shared object. Do I need to include corresponding headers if shared object?

I have to use dlopen() and access functions from shared object in my code. Do I need to include headers of corresponding functions of shared object ?
Because of the way dlopen() and dlsym() operate, I don't see how that would accomplish anything. Very roughly speaking, dlopen() copies the library binary into your program space and adds the addresses of its exported symbols (i.e. global functions & variables) to your program's symbol table.
Because the library was not linked to your program at compile-time, there's no way your code could possibly know the instruction addresses of these new functions tacked on at run-time. The only way to access a run-time dynamically linked symbol is via a pointer obtained from dlsym().
You have to create a function pointer for each and every library definition that you want to use. If you want to call them like regular functions, in C-language you can manually typedef type definitions for the function pointers, specifying their parameters and return values, then you can call the pointers just like regular functions. But note that you have to define all of these manually. Including the library header doesn't help.
In C++ I think there are issues with storing dlsym() output in a typedef'd pointer due to stricter standards, but this should work in C:
addlib.c (libaddlib.dylib):
int add(int x, int y) {
return x+y;
}
myprogram.c:
#include <stdio.h>
#include <dlfcn.h>
typedef int (*add_t)(int, int);
int main() {
void *lib_handle;
add_t add; // call this anything you want...it's a pointer, it doesn't care
lib_handle = dlopen("libaddlib.dylib", RTLD_NOW);
if (lib_handle == NULL) {
// error handling
}
add = (add_t)dlsym(lib_handle, "add");
if (add == NULL) {
// error handling
}
printf("Sum is %d\n", add(17, 23));
dlclose(lib_handle); // remove library from address space
return 0;
}
(Update: I compiled the dylib and myprogram...it works as expected.)

Objective-C block parameters

Say we have this block:
int (^aBlock)(BOOL) = ^(BOOL param) { ...
My current understanding of this is: the first int is the return type, (^aBlock)(BOOL) gives the name of the method and the type of its parameter, and = ^(BOOL param) is the parameter's name inside the block ... plus the parameter's type again?
Why is the syntax such that we have to list the parameter type twice? Could the two types ever be different?
It is not quite "listing the parameter type twice", you are in the first case declaring the type of a block variable, and in the second case you are defining a block literal.
Then you are assigning the literal to the value of the variable. You could even do something like this, which is equivalent and better illustrates the fact that these are really two totally independent declarations, despite being associated with an assign statement:
id thisBlock = ^id (id x, NSUInteger idx) {
NSLog(#"x = %#",x);
return x;
};
id (^thatBlock)(id obj, NSUInteger index) = thisBlock;
The fact that they are independent of each other means it's probably not even correct to attempt to provide some kind of transference or inheritance of typing information from the left hand side of the expression to the right. And yes, the types can be different - consider this code compiles and executes just fine:
id (^thatBlock)(NSArray *, NSDictionary *, NSString *) = ^id (id x, id y, id z) {
NSLog(#"x = %#",x);
return x;
};
thatBlock(#[],#{},#"");
Hope this helps!
Why is the syntax such that we have to list the parameter type twice?
The block is designed in this way, and so you can do it like this:
int (^aBlock)(BOOL);
aBlock = ^(BOOL param) {
...
};
It just likes
- (int)aMethodWithParam:(BOOL)param;
- (int)aMethodWithParam:(BOOL)param {
...
}
Could the two types ever be different?
Nope, and what's more, the order of the types should be the same, i.e.:
int (^aBlock)(BOOL, NSString*) = ^(BOOL param, NSString *aString) {
...
};
And here's a clear figure for block:
The code snippet you have given isn't a block declaration: it's a block declaration and a block definition. First, you declare an identifier named aBlock:
int (^aBlock)(BOOL)
then you define a block:
^(BOOL param) { ...
Both of these are parsed and evaluated separately. Since you are assigning one to the other, the compiler does a type-check to make sure that the expression on the left hand side (your aBlock declaration) is of the same type as the expression on the right hand side (the block definition).
So, the answer is, these parts need to be evaluated separately. Since the block definition is being compiled on its own, you have to include the type of param, because otherwise the compiler won't know what type it should be. (Yes, you could make an exception in this case, and look across the assignment, but everywhere else in the C language you declare an identifier by giving a type first, so why do it differently here?)
But -- you may say -- if that's true why didn't I have to define the return type (int) on the right-hand side?
Very astute of you. The answer is that, when writing a block expression, you don't need to define the return type, because the compiler can infer it from the return statement (or lack thereof) inside the block.
(So why do you have to include return types with function definitions? Well, history, I guess. Programming language definitions were created by imperfect humans.)
According to Ry's Objective C Tutorial:
Blocks use all the same mechanics as normal functions. You can declare a block variable just like you would declare a function.
NSInteger (^BlocksAddition)(NSInteger x,NSInteger y)=^NSInteger(NSInteger x, NSInteger y){
return x+y;
};
NSUInteger result=BlocksAddition(4,5);
NSLog(#"Addition Result:%d",result);

Marshalling simple and complex datatypes to/from Object^% / void*

I guess this will be simple for C++/CLI gurus.
I am creating a wrapper which will expose high-performance C++ native classes to C# WinForms application.
Everything went fine with simple known objects and I could wrap also a callback function to delegate. But now I am a bit confused.
The native C++ class has a following method:
int GetProperty(int propId, void* propInOut)
At first I thought I could use void* as IntPtr, but then I found out that I need to access it from C#. So I thought about a wrapper method:
int GetProperty(int propId, Object^ propInOut)
but as I looked through the C++ source, I found out that the method needs to modify the objects. So obviously I need:
int GetProperty(int propId, Object^% propInOut)
Now I cannot pass Objects to native methods so I need to know how to treat them in the wrapper. As the caller should always know what kind of data he/she is passing/receiving, I declared a wrapper:
int GetProperty(int propId, int dataType, Object^% propInOut)
I guess, I can use it to pass reference and value types, for example, an int like this:
Object count = 100; // yeah, I know boxing is bad but this will not be real-time call anyway
myWrapper.GetProperty(Registry.PROP_SMTH, DATA_TYPE_INT, ref count);
I just added a bunch of dataType constants for all the data types I need:
DATA_TYPE_INT, DATA_TYPE_FLOAT, DATA_TYPE_STRING, DATA_TYPE_DESCRIPTOR, DATA_TYPE_BYTE_ARRAY
(DATA_TYPE_DESCRIPTOR is a simple struct with two fields: int Id and wstring Description - this type will be wrapped too, so I guess marshaling will be simple copying data back and forth; all the native strings are Unicode).
Now, the question is - how to implement the wrapper method for all these 5 types?
When I can just cast Object^% to something (is int, float safe to do that?) and pass to native method, when do I need to use pin_ptr and when I need some more complex marshaling to native and back?
int GetProperty(int propId, int dataType, Object^% propInOut)
{
if(dataType == DATA_TYPE_INT)
{
int* marshaledPropInOut = ???
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more?
return result;
}
else
if(dataType == DATA_TYPE_FLOAT)
{
float* marshaledPropInOut = ???
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more ?
return result;
}
else
if(dataType == DATA_TYPE_STRING)
{
// will pin_ptr be needed or it is enough with the tracking reference in the declaration?
// the pointers won't get stored anywhere in C++ later so I don't need AllocHGlobal
int result = nativeObject->GetProperty(propId, (void*)marshaledPropInOut);
// need to do anything more?
return result;
}
else
if(dataType == DATA_TYPE_BYTE_ARRAY)
{
// need to convert form managed byte[] to native char[] and back;
// user has already allocated byte[] so I can get the size of array somehow
return result;
}
else
if(dataType == DATA_TYPE_DESCRIPTOR)
{
// I guess I'll have to do a dumb copying between native and managed struct,
// the only problem is pinning of the string again before passing to the native
return result;
}
return -1;
}
P.S. Maybe there is a more elegant solution for wrapping this void* method with many possible datatypes?
It doesn't necessarily make sense to equate a C# object to a void*. There isn't any way to marshal arbitrary data. Even with an object, C# still knows what type it is underneath, and for marshaling to take place -- meaning a conversion from the C++ world to C# or vice-versa -- the type of data needs to be known. A void* is just a pointer to memory of a completely unknown type, so how would you convert it to an object, where the type has to be known?
If you have a limited number of types as you describe that could be passed in from the C# world, it is best to make several overloads in your C++/CLI code, each of which took one of those types, and then you can pin the type passed in (if necessary), convert it to a void*, pass that to your C++ function that takes a void*, and then marshal back as appropriate for the type.
You could implement a case statement as you listed, but then what do you do if you can't handle the type that was passed in? The person calling the function from C# has no way to know what types are acceptable and the compiler can't help you figure out that you did something wrong.

Difference between value parameter and reference parameter?

Difference between value parameter and reference parameter ? This question is asked sometime by interviewers during my interviews. Can someone tell me the exact difference that is easy to explain with example? And is reference parameter and pointer parameter are same thing ?
Thanks
Changes to a value parameter are not visible to the caller (also called "pass by value").
Changes to a reference parameter are visible to the caller ("pass by reference").
C++ example:
void by_value(int n) { n = 42; }
void by_ref(int& n) { n = 42; }
void also_value(int const& n); // Even though a reference is used, this is
// semantically a value parameter---though there are implementation
// artifacts, like not being able to write "n = 42" (it's const) and object
// identity (&n here has different ramifications than for by_value above).
One use of pointers is to implement "reference" parameters without using a special reference concept, which some languages, such as C, don't have. (Of course you can also treat pointers as values themselves.)
The main difference is whether the object passed is copied. If it's a value parameter the compiler must generate such code that altering the function parameter inside the function has no effect on the original object passsed, so it will usually copy the object. In case of reference parameters the compiler must generate such code taht all operations are done on the original object being passed.
A pointer is a low-level way of representing a reference, so passing a pointer (by value) is how languages like C typically achieve pass by reference semantics.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or by copy.
There are basically three kinds of parameters; pointer, reference and direct.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or bycopy.
Pointers are also passed by value, but rather than sending the actual value, the caller sends the address of the value. This means that by following this pointer, the receiver can modify the argument. Note that changes made to the actual pointer still aren't reflected back to the caller.
The final form, call-by-reference, is sort of a middle ground between these two approaches. Essentially it can be thought of as a pointer that looks like a value.
It is worth mentioning that at the core of it all, parameters are always passed by value, but different languages have different ways of implementing reference semantics (see Kylotans answer).
// Example using C
// bycopy
int multiply(int x, int y) {
return x * y;
}
void multiply_p(int *x, int y) {
*x *= y;
}
int main () {
int i, j, k;
i = 20;
j = 10;
k = multiply(i,j); // k is now 200
multiply_p(&i, k); // i is now 4000 (200 * 20)
return 0;
}
Pseudocode:
Pass by Value:
void setTo4(value) { // value is passed by value
value = 4;
}
int x = 1;
setTo4(x);
// x is still 1
Pass by Reference:
void setTo4(value) { // value is passed by reference
value = 4;
}
int x = 1;
setTo4(x);
// x is 4