I have a function that is connected to the "changed" signal for a combobox in gtk, which in turn calls another function read_button_config.
The read_button_config takes the main window, a combobox and a vcontainer which I had not declared globally as parameters
Which way is better for passing these parameters:
- declaring the parameters globally
- passing the parameters as a struct to the first function, and passing the struct members to the read_button_config function?
Please let me know why you think either is better, I want to know what is a better way for future development
Which way is better for passing these parameters: - declaring the
parameters globally - passing the parameters as a struct to the first
function, and passing the struct members to the read_button_config
function?
The latter is the preferred way; that is the purpose of the user_data parameter to signal functions, after all.
Declaring them globally isn't bad. Rather, using the user_data is idiomatic. It's a bit harder since you have to manage the memory for the user_data yourself, but using user_data keeps your code modules more self-contained. You will need to decide what you want to do.
– andlabs
Related
In Go source I have
type T struct {
// some data
}
func (t *T)M(arg0 SomeType1) {
// some computations
}
var Obj *T
In C sources I have
// SomeType1C is equivalent to SomeType1.
typedef void (*CallbackFunc)(SomeType1C);
// callback will be called !after! register_callback function returns.
void register_callback(CallbackFunc callback);
I would like to use Obj.M as callback for register_callback in C.
On MS Windows for winapi I pass smth like C.CallbackFunc(unsafe.Pointer(syscall.NewCallback(Obj.M))) to register_callback for this (not sure is it fully correct, but at least this works). But where is no NewCallback for non-Windows systems.
PS:
I'm sure that callback is registered after T is initialised and removed before T is removed.
I may have multiple instances of T and some of them may be used to callback's 'source' at same time (so T is not some kind of singltone).
Function pointer callbacks in GoLang's wiki uses gateway function, but I don't see how to adequate use it with struct's method.
Base idea:
Use exported callback as a proxy between C and Go:
//export callback
func callback(data0 SomeType1C, data1 Data){ // data1 - data passed to register_callback_with_data
obj := convertDataToObj(data1)
obj.M(data0)
}
and register it like this:
register_callback_with_data(callback, convertObjToData(obj));
Where are 3 ways: wrong (and easy), limited (medium) and right (hard).
Wrong (and easy) way:
Pass pointer to Go struct into C (as in original answer). This is totally wrong because Go runtime can move struct in memory. Usually this operation is transparent (all Go pointers will be updated automatically). But pointers in C memory to this struct will not be updated and program may crash/UB/... when tries to use it. Do not use this way.
Limited (medium) way:
Similar to previous, but with Go struct allocated in C memory:
Obj = (*T)(C.calloc(C.size_t(unsafe.Sizeof(T{}))))
In this case Obj can not be moved by Go runtime because it is in C memory. But now if Obj has pointers to Go memory (fields with *-variables, maps, slices, channels, function-pointers, ...) then this also may cause crash/UB/... This is because:
if there are no (other) Go pointers to the same variable (memory), then Go runtime thinks that this memory is free and can be reused,
or, if there is other Go pointer to same variable (memory), then Go can move this variable in memory.
So, use this way only if struct has no pointers to Go memory. Usually this means that struct contains only primitive fields (ints, floats, bool).
Right (and hard) way:
Assign id (of integer type for example) for each object of type T and pass this id into C. In exported callback you should convert id back to object. This is right way with no limitation, so this way may be used always. But this way requires to maintain some array/slice/map to convert between objects and ids. Moreover, this convertation may require some synchronization for thread-safe (so see sync.Mutex and sync.RWMutex).
Original answer:
Not best answer and has restrictions, but no other suggested. In my case I can pass additional data to register_callback. This data will be passed back to callback on each call. So I pass unsafe.Pointer(Obj) as data and use gateway function:
//export callback
func callback(data SomeType1C, additionalData unsafe.Pointer){
obj := (*T)(additionalData) // Get original Obj (pointer to instance of T)
dataGo := *(*SomeType1)(unsafe.Pointer(&data)) // Cast data from C to Go type
obj.M(dataGo)
}
and register it like this:
register_callback_with_data(callback, unsafe.Pointer(Obj));
PS: but still want to know how to do this better in general case (without additional data).
Here's the question and the problem I'm facing.
I had a task to create a new kernel function in OpenBSD (into syscalls.master). It is called sys_eventopen(int id). The thing is that into sys_generic.c where the function should be implemented, right into the implementation I need to modify the value of a struct variable like this:
struct resource{
int id=0;
int is_busy=0;
}res;
The thing is that I want to be able to access the res resource into the implementation of the sys_eventopen(). I want to know whether it's possible to declare a global variable into the sys_generic.c so that I can access it into the function or rewrite all the functions so that I could send that variable as a parameter. Thanks in advance.
I have come across the function pointers. I know understand how this works. But i am not pretty sure, in what situation it will use. After some google and other search in Stack Overflow. I came know to know that it will use in two case
when callback mechanism is used
Store a array of functions, to call dynamically.
In this case also, why don't we call function directly. In the call back Mechanism also, as particular events occur, callback pointer is assigned to that function(Address). Then that is called. Can't we call function directly rather than using the function pointer. Can some some one tell me, what is the exact usage of Function pointer and in what situation.
Take a look at functions needing a callback, like
bsearch or qsort for the comparator, signal for the handler, or others.
Also, how would you want to program other openly-extensible mechanisms, like C++-like virtual-dispatch (vptr-table with function-pointers and other stuff)?
In short, function-pointers are used for making a function generic by making parts of the behavior user-defined.
One of the situation when function pointers would be useful is when you are trying to implement callback functions.
For example, in a server that I've been implementing in C and libevent accepts a message from clients and determine what to do. Instead of defining hundreds of switch-case blocks, I store function pointer of function to be called in a hash table so the message can be directly mapped to the respective function.
Event handling in libevent API(read about event_new()) also demonstrates the usefulness of having function points in APIs such that users can define their own behaviour given a certain situation and need not to modify the master function's code, which creates flexibility while maintaining certain level of abstraction. This design is also widely used in the Kernel API.
You said:
In the call back Mechanism also, as particular events occur, callback pointer is assigned to that function(Address).
Callback functions are registered at a very different place than where the callback functions are called.
A simple example:
In a GUI, the place where you register a function when a button is pressed is your toplevel application setup. The place where the function gets called is the implementation of the button. They need to remain separate to allow for the user of the button to have the freedom of what they wish to do when a button is pressed.
In general, you need a function pointer when the pointer needs to be stored to be used at a future time.
In the case of a callback situation, including interrupt driven code, a sequence of call backs or interrupts may occur for a single logical process. Say you have a set of functions like step1(), step2(), ... , to perform some process where a common callback is being used to step through a sequence. The initial call sets the callback to step1(), when step1() is called, it changes the pointer to function to step2() and initiates the next step. When that step completes, step2() is called, and it can set a pointer to function to step3(), and so on, depending on how many steps it takes to perform the sequence. I've mostly used this method for interrupt driven code.
Sometimes I use function pointers just to make (as I see it) the code more legible, and easier to change. But this is a matter of taste, there is no one 'correct' way. It's possible that the function pointer code will be slower, but probably only slightly and of course as far as performance goes it's always a matter of measuring, and usually more a matter of choosing better algorithms than of micro-optimisation.
One example is when you have two functions, with identical and long argument lists and sometimes you want to call one and sometimes the other. You could write
if ( condition)
{ one( /* long argument list */);
}
else
{ other( /* long argument list */);
}
or you could write
(condition ? one : other)(/* long argument list */);
I prefer the second as there is only one instance of the long argument list, and so it's easier to get right, and to change.
Another case is implementing state machines; one could write
switch( state)
{ case STATE0: state = state0_fun( input); break;
// etc
}
or
typedef int (*state_f)( void*);
state_f statefs[] = { state0_fun /* etc */}
state = statefs[ state](input);
Again I find the second form more maintainable, but maybe that's just me.
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.