I've recently inherited some (undocumented) C code that contains several instances of this pattern:
void my_function(void *_foo, const void *_bar) {
MyType *foo = (MyType *)_foo;
MyType *bar = (MyType *)_bar;
I'm pretty familiar with C but I can't for the life of me figure out why the function consumes void pointers. Isn't this just going to suppress potentially helpful compiler warnings if the wrong type is passed in anywhere? Or is there a sensible method behind it that I am new to?
Generally, the void * is used as an abstraction i.e. you can pass pointers of different types using void * to a function and later depending on appropriate conditions, you can typecast the void * to the correct type and use it.
Another usage could be when the calling function is in a logically separate unit like a library and doesn't have access to the correct type to which the pointer belongs. But, still the data has to pass through that function.
I used to use such abstraction mechanisms with callbacks. For Example, if I am calling a library which function which eventually calls my callback and I want some data of application in my callback, but, the library function has no use of it, then I will pass such data typecasted as void * to the library function and on receiving that data in the callback, I will typecast it to appropriate type and use it.
Related
I've seen a good deal of C libraries that do not present the objects they deal with internally as distinct types, but instead wrap them with void pointers before letting you access them. In practice, the "private" source files look something like:
typedef struct {
int value;
} object;
void * object_new(void)
{
object *o = malloc(sizeof(object));
o->value = 1;
return o;
}
int object_get(void *o)
{
return (object *)o->value;
}
void * object_free(void *o)
{
free(o);
}
And in the main header you have only:
void * object_new(void);
int object_get(void *o);
void * object_free(void *o);
Now I wonder: is there a particular reason they do so? If the idea is to ensure the API user has no access to the internals of the object, isn't it sufficient to only expose the type name in the main library header, and to hide the details of the underlying structure (or whatever be the actual object) in the implementation files?
The reason to hide the types behind void pointers could be a (misguided) attempt to hide (in the sense of modular programming) the internal details. This is dangerous, as it throws any type checking the compiler might do right out the window.
Better would be something along the lines:
for-user.h:
struct internalstuff;
void somefunc(struct internalstuff *p);
for-internal-use.h:
#include "for-user.h"
struct internalstuff { ...};
implementation.c:
#include "for-internal-use.h";
void somefunc(struct internalstuff *p)
{
...
}
This way nobody will mix up internalstuff with a random string or the raw result from malloc(3) without getting at least a warning. As long as you only mention pointers to struct internalstuff in C it is fine not to have the definition of the struct at hand.
Something along the same lines can be done in C++ with class, and I'd be suprised if Objective C doesn't allow the same. But the object oriented programming languages have their own, much more flexible, tools for this. There you can define a bare-bones base class to export, while internally extensions are used. Take a look at a good C++ book for details (there are extensive lists here).
In a world of objects (Obj-C and C++), I believe the reason is mostly to do with inheritance. If a subclass is created from the base class, then there is no problem with the type of the return value when creating a new instance of the class. With just straight C, there does not appear to be a clear cut reason as no internal details are revealed or dependencies created.
You're correct.. the idea in most of these cases is to restrict the API user from the internals of the object. The decision about type names though really is just a matter of style. If you were to expose the type name in the header as you suggest (which some APIs do), it would probably look something like:
typedef void* object;
There is no real advantage or disadvantage to doing this from the compiler's point of view. Although it does give the API user a better understanding of what's going on:
object object_new(void);
int object_get(object o);
void object_free(object o);
I've been tinkering with some code in a effort to understand OOP using c.
I really like this style and want to use it. The code sample works great if another class creates an instance of FooOBJ.
How can FooOBJ reference itself to change its own variables?
Do I need to make a copy of foo in the constructor or something like that or am I wandering away from the right way to use this methodology?
struct fooobj {
int privateint;
char *privateString;
};
FooOBJ newFooOBJ(){
FooOBJ foo=(FooOBJ)malloc(sizeof(struct fooobj));
bzero(foo, sizeof(struct fooobj));
return foo;
}
void setFooNumber(FooOBJ foo,int num){
if(foo==NULL) return; /* you may chose to debugprint something
*instead
*/
foo->privateint=num;
}
void setmyself(int val)
{
//this->privateint = val
}
Well, any function operating on an instance of your "class" will have to take a pointer to the instance. This happens automatically and implicitly in C++, but in C you'll have to pass a "this" pointer everywhere.
What this means is that your setFooNumber has the right signature for a "member function", whereas setmyself does not.
There's a reason C++ and other OO languages have an implicit parameter to instance methods. The only way this can be done is if you explicitly pass a this pointer. A function doesn't have access to something that isn't declared in an appropriate scope: locally or globally (parameters being local).
To understand OOP in C, you'll need to understand how to simulate pure OO code in a procedural way.
In a C function declaration, I have seen this parameter definition:
void *userData
so, what exactly is that? My guess: the void says it can be anything arbitrary, or even nothing. Almost similar to id of objective-c. It just allows to pass in whatever data structure you like.
The star in front of userData says, that the argument must be passed in by reference.
So when using this stuff in the function body, typically it must be casted and dereferenced.
So if I pass in an pointer to SomeClass instance, I would get that like this:
SomeClass *myObj = (SomeClass*)userData;
In the case I had nothing special to pass along, I would provide NULL as argument.
Are my assumptions correct? Or did I get something wrong?
A void * is a pointer to a structure of unknown type. You can think of it as "a pointer to anything". It's not the same as Objective-C's id type, which is the type of any object. An id looks like this:
typedef struct objc_object {
Class isa;
} *id;
Typically in Objective-C (and I'm sure in C too) a framework might use some callback to tell you something. That callback will often take a parameter containing data that you give it - perhaps the object that started the action, and that needs to know that something's happened. A void * parameter lets the framework define a callback without depending on your code, so you can put anything you like into the callback. (Of course that means you also have to ensure that you cast your void *userData back into the appropriate type.)
void * means pointer to anything. So, you could pass anything "by reference" via void * argument. userData parameter name suggests (but is only a suggestion so it may vary across various APIs), that this argument is some arbitrary user-supplied data. That is, function in question will do nothing with it, just store, and give you it back some time. For example, in GTK+ you can attach a callback to some event. You can pass your own data to g_signal_connect as user_data argument, and in event handler, GTK+ will pass you your data back:
GtkWidget *button = gtk_button_new ();
const char *data = "Hello World;)";
g_signal_connect (button, "clicked", on_clicked, data);
(...)
void on_clicked (GtkWidget *widget, void * data)
{
const char *text = (const char *)data;
printf ("%s\n", text); // will print "Hello World;)"
}
void * is a pointer to any data type.
Note that it is not necessarily the right size for a pointer to a function.
Without seeing the actual code I'm guessing the parameter belongs to a function which takes a callback? If so it is probably a piece of context which, as you say, you can set to whatever you want. When the function invokes your callback it will pass this context along, which means you don't need a global to store this data.
Your understanding is essentially correct, although it is called a pointer not a reference. This is usually a mechanism for letting users "extend" a data structure by passing in a block of any type of data. An example I have seen this used is for nodes of a tree display in a GUI. The GUI framework adds the void pointer so that when a user clicks a node of this tree, you can pull more meaningful information about the node than just its name into your calling routine. Since only you know what type of data would be meaningful to your application, the type is simply a void*.
Also note that you are almost always responsible for managing the memory for userData.
I'm writing a wrapper around a C library in Objective-C. The library allows me to register callback functions when certain events occur.
The register_callback_handler() function takes a function pointer as one of the parameters.
My question to you gurus of programming is this: How can I represent an Objective-C method call / selector as a function pointer?
Would NSInvocation be something useful in this situation or too high level?
Would I be better off just writing a C function that has the method call written inside it, and then pass the pointer to that function?
Any help would be great, thanks.
Does register_callback_handler() also take a (void*) context argument? Most callback APIs do.
If it does, then you could use NSInvocation quite easily. Or you could allocate a little struct that contains a reference to the object and selector and then cobble up your own call.
If it only takes a function pointer, then you are potentially hosed. You need something somewhere that uniquely identifies the context, even for pure C coding.
Given that your callback handler does have a context pointer, you are all set:
typedef struct {
id target;
SEL selector;
// you could put more stuff here if you wanted
id someContextualSensitiveThing;
} TrampolineData;
void trampoline(void *freedata) {
TrampolineData *trampData = freedata;
[trampData->target performSelector: trampData->selector withObject: trampData-> someContextualSensitiveThing];
}
...
TrampolineData *td = malloc(sizeof(TrampolineData));
... fill in the struct here ...
register_callback_handler(..., trampoline, td);
That is the general idea, anyway. If you need to deal with non-object typed arguments and/or callbacks, it gets a little bit trickier, but not that much. The easiest way is to call objc_msgSend() directly after typecasting it to a function pointer of the right type so the compiler generates the right call site (keeping in mind that you might need to use objc_msgSend_stret() for structure return types).
I have a C function named SetParams(...) with a variable number of arguments. This function sets up a static data structure (let us name it Data). SetParams is used with pairs of arguments, e.g. SetParams("paramA", paramA_value, "paramB", paramB_value) etc. It can also be called many times, e.g.
SetParams("paramA", paramA_value);
SetParams("paramB", paramB_value);
...
When all 'parameters' have been set, another function is called (let us name it Execute) that takes no args:
Execute();
// uses data from static 'Data' and performs error_handling and execution
I was wondering if I could structure this kind of code in a more object-oriented way. So, I would like some advice, especially for error-handling, since some pairs of args may contradict others.
The general practice for creating an object oriented design in C is for every method you have you will pass in a reference to a struct which is used to store all the classes member variables. In otherwords in C++ where you'd have listObj.clear() you have in C list_clear(&listObj).
This is kind of ugly, but it's necessary unless you want to use static member variables and limit the implementation to being used only once.
In the example below, notice how in each method a reference to a struct ParamUtilObj is passed in.
// --- paramUtil.h
// Stores all the objects member variables (public and private)
struct ParamUtilObj {
int paramCnt;
char param1[25];
char param2[25];
...
};
bool paramUtil_initialize( struct* ParamUtilObj pData );
bool paramUtil_addParam( struct* ParamUtilObj pData, const char* pKey, const char* pValue );
bool paramUtil_execute( struct* ParamUtilObj pData);
With respect to variadic methods. I'd try to avoid them if possible and just add them in one at a time. The business logic to validate the params is an entirely different topic in my opinion. I'd need more info to recommend the best approach. But... It seems to me since you're going to have to do validation such as if( MethodA ) then check for presence of some other argument... it might be easier to create several SetParam methods for each MethodType which the user could specify in the script.
I would recommend using a linked list to store your params and put all your methods as function pointers to a struct.
struct MyClass {
struct LinkedList* params;
void (*setParams)(...);
void (*execute)()
}
the linked list would be a key value pair
struct LinkedList {
struct LinkedList *next;
char * key;
char * value;
}
I dont know how you have your SetParams implemented, from the sound it just does a little bit of parsing and storing and forwards error handling downstream to the Execute call.
Since you are using variable length arguments, are you using the va_* macros? Doing so with a format string might allow you to insert the error handling into your SetParams call and allow Execute to just iterate over the values and do its thing.
Generally, if you have a function that handles setting parameters that should be where you manage errors associated with setting parameters. Errors encountered in the execution of command should be addressed in the execute function.
You cannot do it this way, because in C variadic functions don't know the number of arguments you've supplied, so you need somehow let function know it, like specifying number of params as first parameter or use printf way, when number of parameters can be found from format string.