C return function depending on parameter - c

I have a function which takes a callback as parameter, its signature is:
typedef void(*callback_type)(const* uint32_t data, unint8_t size);
void set_callback(callback_type callback);
The two parameters taken by the callback function are used by a struct so I would like to bind the callback to the struct. C++ has tools to deal with this kind of problems (member functions, lambdas, std::bind, ...). For example, the code I'm trying to achieve in C is equivalent to the C++ code:
set_callback([&](const uint32_t* data, uint8_t size) -> void {
use_data(&the_struct, data, size);
});
The solution I'm looking for has some requirements:
Language: C (or assembly if anyone is willing to)
If possible with no imports (these including c standard library)
Be independent of the compiler (ie. no blocks from GCC or CLang)
Through my researches, I have found the following code, but it does not work in my case and does not really match requirements as it is dependent on non standard features provided by gcc (nested functions and statement expressions):
#define lambda(lambda$_ret, lambda$_args, lambda$_body)\
({\
lambda$_ret lambda$__anon$ lambda$_args\
lambda$_body\
&lambda$__anon$;\
})
Also note that it is possible to modify code in order to take a void pointer (as user data) in a callback which would solve the problem. This is the best solution I have so far and might be the cleanest overall. However, I'd like a solution that does not requires such trick.
Even if you only have a partial solution, I'd be happy to hear about it.
Thanks for taking the time for reading the question and have a good day!
Edit 1:
The c++ code involving a lambda does not work (because the lambda captures...). For this to work, std::function or templated arguments must be used. But the point is still clear I think.
Thanks to tstanisl for pointing this out.
Edit 2:
When I wrote "used by a struct" this effectively makes no sense. What I meant was : a function will use the data provided (data and size parameters) to update members of the structure and do some other computation. I hope this is more clear.
Thanks to '4386427' and 'Gaurav Pathak' for their comments.

Based on the understanding and per your requirement, as you mentioned that you cannot change the function prototype to add extra argument for passing reference of the structure, you can use a global structure variable, and then you can use that global variable inside the Callback function (hope you can edit the Callback function or provide a custom Callback function) to update the structure members (you need to take care of Synchronization issues).
To explain the above statement, I am providing a very simple example below:
#include<stdio.h>
#include<stdint.h>
typedef struct _the_struct {
int data;
int size;
}TheStruct;
TheStruct structVar;
typedef void(*callback_type)(const uint32_t *data, uint8_t size);
void set_callback(callback_type callback);
void my_callback(const uint32_t *data, uint8_t size);
void set_callback(callback_type callback) {
int a = 5;
callback(&a, 4);
}
void my_callback(const uint32_t *data, uint8_t size)
{
structVar.data = *data;
structVar.size = size;
printf("Data: %d Size: %d\n", *data, size);
}
int main(void)
{
set_callback(my_callback);
printf("StructData: %d StructSize: %d\n", structVar.data, structVar.size);
}
I hope the explanation provides some helpful information to you.

Related

Generic hashtable in C

I'm trying to create a generic hash table in C. I've read a few different implementations, and came across a couple of different approaches.
The first is to use macros like this: http://attractivechaos.awardspace.com/khash.h.html
And the second is to use a struct with 2 void pointers like this:
struct hashmap_entry
{
void *key;
void *value;
};
From what I can tell this approach isn't great because it means that each entry in the map requires at least 2 allocations: one for the key and one for the value, regardless of the data types being stored. (Is that right???)
I haven't been able to find a decent way of keeping it generic without going the macro route. Does anyone have any tips or examples that might help me out?
C does not provide what you need directly, nevertheless you may want to do something like this:
Imagine that your hash table is a fixed size array of double linked lists and it is OK that items are always allocated/destroyed on the application layer. These conditions will not work for every case, but in many cases they will. Then you will have these data structures and sketches of functions and protototypes:
struct HashItemCore
{
HashItemCore *m_prev;
HashItemCore *m_next;
};
struct HashTable
{
HashItemCore m_data[256]; // This is actually array of circled
// double linked lists.
int (*GetHashValue)(HashItemCore *item);
bool (*CompareItems)(HashItemCore *item1, HashItemCore *item2);
void (*ReleaseItem)(HashItemCore *item);
};
void InitHash(HashTable *table)
{
// Ensure that user provided the callbacks.
assert(table->GetHashValue != NULL && table->CompareItems != NULL && table->ReleaseItem != NULL);
// Init all double linked lists. Pointers of empty list should point to themselves.
for (int i=0; i<256; ++i)
table->m_data.m_prev = table->m_data.m_next = table->m_data+i;
}
void AddToHash(HashTable *table, void *item);
void *GetFromHash(HashTable *table, void *item);
....
void *ClearHash(HashTable *table);
In these functions you need to implement the logic of the hash table. While working they will be calling user defined callbacks to find out the index of the slot and if items are identical or not.
The users of this table should define their own structures and callback functions for every pair of types that they want to use:
struct HashItemK1V1
{
HashItemCore m_core;
K1 key;
V1 value;
};
int CalcHashK1V1(void *p)
{
HashItemK1V1 *param = (HashItemK1V1*)p;
// App code.
}
bool CompareK1V1(void *p1, void *p2)
{
HashItemK1V1 *param1 = (HashItemK1V1*)p1;
HashItemK1V1 *param2 = (HashItemK1V1*)p2;
// App code.
}
void FreeK1V1(void *p)
{
HashItemK1V1 *param = (HashItemK1V1*)p;
// App code if needed.
free(p);
}
This approach will not provide type safety because items will be passed around as void pointers assuming that every application structure starts with HashItemCore member. This will be sort of hand made polymorphysm. This is maybe not perfect, but this will work.
I implemented this approach in C++ using templates. But if you will strip out all fancies of C++, in the nutshell it will be exactly what I described above. I used my table in multiple projects and it worked like charm.
A generic hashtable in C is a bad idea.
a neat implementation will require function pointers, which are slow, since these functions cannot be inlined (the general case will need at least two function calls per hop: one to compute the hash value and one for the final compare)
to allow inlining of functions you'll either have to
write the code manually
or use a code generator
or macros. Which can get messy
IIRC, the linux kernel uses macros to create and maintain (some of?) its hashtables.
C does not have generic data types, so what you want to do (no extra allocations and no void* casting) is not really possible. You can use macros to generate the right data functions/structs on the fly, but you're trying to avoid macros as well.
So you need to give up at least one of your ideas.
You could have a generic data structure without extra allocations by allocating something like:
size_t key_len;
size_t val_len;
char key[];
char val[];
in one go and then handing out either void pointers, or adding an api for each specific type.
Alternatively, if you have a limited number of types you need to handle, you could also tag the value with the right one so now each entry contains:
size_t key_len;
size_t val_len;
int val_type;
char key[];
char val[];
but in the API at least you can verify that the requested type is the right one.
Otherwise, to make everything generic, you're left with either macros, or changing the language.

Data encapsulation in C

I am currently working on an embedded system and I have a component on a board which appears two times. I would like to have one .c and one .h file for the component.
I have the following code:
typedef struct {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
} ads1248_options_t;
Those are all hardware settings. I create two instances of this struct (one for each part).
Now I need to keep an array of values in the background. E.g. I can read values from that device every second and I want to keep the last 100 values. I would like this data to be non-accessible from the "outside" of my component (only through special functions in my component).
I am unsure on how to proceed here. Do I really need to make the array part of my struct? What I thought of would be to do the following:
int32_t *adc_values; // <-- Add this to struct
int32_t *adc_value_buffer = malloc(sizeof(int32_t) * 100); // <-- Call in initialize function, this will never be freed on purpose
Yet, I will then be able to access my int32_t pointer from everywhere in my code (also from outside my component) which I do not like.
Is this the only way to do it? Do you know of a better way?
Thanks.
For the specific case of writing hardware drivers for a microcontroller, which this appears to be, please consider doing like this.
Otherwise, use opaque/incomplete type. You'd be surprised to learn how shockingly few C programmers there are who know how to actually implement 100% private encapsulation of custom types. This is why there's some persistent myth about C lacking the OO feature known as private encapsulation. This myth originates from lack of C knowledge and nothing else.
This is how it goes:
ads1248.h
typedef struct ads1248_options_t ads1248_options_t; // incomplete/opaque type
ads1248_options_t* ads1248_init (parameters); // a "constructor"
void ads1248_destroy (ads1248_options_t* ads); // a "destructor"
ads1248.c
#include "ads1248.h"
struct ads1248_options_t {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
};
ads1248_options_t* ads1248_init (parameters)
{
ads1248_options_t* ads = malloc(sizeof(ads1248_options_t));
// do things with ads based on parameters
return ads;
}
void ads1248_destroy (ads1248_options_t* ads)
{
free(ads);
}
main.c
#include "ads1248.h"
int main()
{
ads1248_options_t* ads = ads1248_init(parameters);
...
ads1248_destroy(ads);
}
Now the code in main cannot access any of the struct members, all members are 100% private. It can only create a pointer to a struct object, not an instance of it. Works exactly like abstract base classes in C++, if you are familiar with that. The only difference is that you'll have to call the init/destroy functions manually, rather than using true constructors/destructors.
It's common that structures in C are defined completely in the header, although they're totally opaque (FILE, for example), or only have some of their fields specified in the documentation.
C lacks private to prevent accidental access, but I consider this a minor problem: If a field isn't mentioned in the spec, why should someone try to access it? Have you ever accidentally accessed a member of a FILE? (It's probably better not to do things like having a published member foo and a non-published fooo which can easily be accessed by a small typo.) Some use conventions like giving them "unusual" names, for example, having a trailing underscore on private members.
Another way is the PIMPL idiom: Forward-declare the structure as an incomplete type and provide the complete declaration in the implementation file only. This may complicate debugging, and may have performance penalties due to less possibilities for inlining and an additional indirection, though this may be solvable with link-time optimization. A combination of both is also possible, declaring the public fields in the header along with a pointer to an incomplete structure type holding the private fields.
I would like this data to be non-accessible from the "outside" of my
component (only through special functions in my component).
You can do it in this way (a big malloc including the data):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
} ads1248_options_t;
void fn(ads1248_options_t *x)
{
int32_t *values = (int32_t *)(x + 1);
/* values are not accesible via a member of the struct */
values[0] = 10;
printf("%d\n", values[0]);
}
int main(void)
{
ads1248_options_t *x = malloc(sizeof(*x) + (sizeof(int32_t) * 100));
fn(x);
free(x);
return 0;
}
You could make a portion of your structure private like this.
object.h
struct object_public {
uint32_t public_item1;
uint32_t public_item2;
};
object.c
struct object {
struct object_public public;
uint32_t private_item1;
uint32_t *private_ptr;
}
A pointer to an object can be cast to a pointer to object_public because object_public is the first item in struct object. So the code outside of object.c will reference the object through a pointer to object_public. While the code within object.c references the object through a pointer to object. Only the code within object.c will know about the private members.
The program should not define or allocate an instance object_public because that instance won't have the private stuff appended to it.
The technique of including a struct as the first item in another struct is really a way for implementing single inheritance in C. I don't recall ever using it like this for encapsulation. But I thought I would throw the idea out there.
You can:
Make your whole ads1248_options_t an opaque type (as already discussed in other answers)
Make just the adc_values member an opaque type, like:
// in the header(.h)
typedef struct adc_values adc_values_t;
// in the code (.c)
struct adc_values {
int32_t *values;
};
Have a static array of array of values "parallel" to your ads1248_options_t and provide functions to access them. Like:
// in the header (.h)
int32_t get_adc_value(int id, int value_idx);
// in the code (.c)
static int32_t values[MAX_ADS][MAX_VALUES];
// or
static int32_t *values[MAX_ADS]; // malloc()-ate members somewhere
int32_t get_adc_value(int id, int value_idx) {
return values[id][value_idx]
}
If the user doesn't know the index to use, keep an index (id) in your ads1248_options_t.
Instead of a static array, you may provide some other way of allocating the value arrays "in parallel", but, again, need a way to identify which array belongs to which ADC, where its id is the simplest solution.

Is it possible to simulate object/instance methods in C?

I'm aware that, because C isn't object oriented, the closest we can get to methods is using function pointers in a struct. This is just a thought exercise, but is it possible to have:
list.add(void* data)
without passing in the list itself as a parameter?
I know that:
list.add(list_t* list, void* data)
would be easy to implement, but is there any way, using whatever parts of C, to simulate a method in this way?
I recognize it's possible the answer is no, but please explain to me if you can! Thanks.
This is the prettiest syntax I got using variadic macros (C99):
#define call(obj, method, ...) ((obj).method(&(obj), __VA_ARGS__))
usage (click for ideone):
struct class {
int a;
int (*method)(struct class* this, int b, int c);
};
int code(struct class* this, int b, int c) {
return this->a*b+c;
}
struct class constructor(int a) {
struct class result = {a, code};
return result;
}
#define call(obj, method, ...) ((obj).method(&(obj), __VA_ARGS__))
#include <stdio.h>
int main() {
struct class obj = constructor(10);
int result = call(obj, method, 2, 3);
printf("%d\n", result);
return 0;
}
Not only instance methods, but you can even have CLOS-style generic methods with the right library. Laurent Deniau's COS library (also see paper: [link]) provides a full OO system you can just #include and start using immediately; the method syntax is no heavier than any other function call.
It's apparently fast, too; the author claims to have gained a performance edge on similar code expressed in Objective-C (I'll take the claim itself with a pinch of salt, but even if they're comparable that's impressive).
To emulate OO method calls, you need objects with class or vtable pointers. If your list_t contains, say, a funcs member that points to a struct containing function pointers, one of which is add, then your usage would be
list->funcs->add(list, data)
which you could capture in a variadic macro:
#define OO(obj, func, ...) (obj)->funcs->func(obj, __VA_ARGS__)
OO(list, add, data);
If you want something simple, you can implement struct member functions using the blocks language extension. Blogged here.
You can use blocks to lambda-capture the associated struct, simulating the this pointer.
There's no virtual dispatch with this approach, so it's up to you whether you consider these true objects.

Implementing different yet similar structure/function sets without copy-paste

I'm implementing a set of common yet not so trivial (or error-prone) data structures for C (here) and just came with an idea that got me thinking.
The question in short is, what is the best way to implement two structures that use similar algorithms but have different interfaces, without having to copy-paste/rewrite the algorithm? By best, I mean most maintainable and debug-able.
I think it is obvious why you wouldn't want to have two copies of the same algorithm.
Motivation
Say you have a structure (call it map) with a set of associated functions (map_*()). Since the map needs to map anything to anything, we would normally implement it taking a void *key and void *data. However, think of a map of int to int. In this case, you would need to store all the keys and data in another array and give their addresses to the map, which is not so convenient.
Now imagine if there was a similar structure (call it mapc, c for "copies") that during initialization takes sizeof(your_key_type) and sizeof(your_data_type) and given void *key and void *data on insert, it would use memcpy to copy the keys and data in the map instead of just keeping the pointers. An example of usage:
int i;
mapc m;
mapc_init(&m, sizeof(int), sizeof(int));
for (i = 0; i < n; ++i)
{
int j = rand(); /* whatever */
mapc_insert(&m, &i, &j);
}
which is quite nice, because I don't need to keep another array of is and js.
My ideas
In the example above, map and mapc are very closely related. If you think about it, map and set structures and functions are also very similar. I have thought of the following ways to implement their algorithm only once and use it for all of them. Neither of them however are quite satisfying to me.
Use macros. Write the function code in a header file, leaving the structure dependent stuff as macros. For each structure, define the proper macros and include the file:
map_generic.h
#define INSERT(x) x##_insert
int INSERT(NAME)(NAME *m, PARAMS)
{
// create node
ASSIGN_KEY_AND_DATA(node)
// get m->root
// add to tree starting from root
// rebalance from node to root
// etc
}
map.c
#define NAME map
#define PARAMS void *key, void *data
#define ASSIGN_KEY_AND_DATA(node) \
do {\
node->key = key;\
node->data = data;\
} while (0)
#include "map_generic.h"
mapc.c
#define NAME mapc
#define PARAMS void *key, void *data
#define ASSIGN_KEY_AND_DATA(node) \
do {\
memcpy(node->key, key, m->key_size);\
memcpy(node->data, data, m->data_size);\
} while (0)
#include "map_generic.h"
This method is not half bad, but it's not so elegant.
Use function pointers. For each part that is dependent on the structure, pass a function pointer.
map_generic.c
int map_generic_insert(void *m, void *key, void *data,
void (*assign_key_and_data)(void *, void *, void *, void *),
void (*get_root)(void *))
{
// create node
assign_key_and_data(m, node, key, data);
root = get_root(m);
// add to tree starting from root
// rebalance from node to root
// etc
}
map.c
static void assign_key_and_data(void *m, void *node, void *key, void *data)
{
map_node *n = node;
n->key = key;
n->data = data;
}
static map_node *get_root(void *m)
{
return ((map *)m)->root;
}
int map_insert(map *m, void *key, void *data)
{
map_generic_insert(m, key, data, assign_key_and_data, get_root);
}
mapc.c
static void assign_key_and_data(void *m, void *node, void *key, void *data)
{
map_node *n = node;
map_c *mc = m;
memcpy(n->key, key, mc->key_size);
memcpy(n->data, data, mc->data_size);
}
static map_node *get_root(void *m)
{
return ((mapc *)m)->root;
}
int mapc_insert(mapc *m, void *key, void *data)
{
map_generic_insert(m, key, data, assign_key_and_data, get_root);
}
This method requires writing more functions that could have been avoided in the macro method (as you can see, the code here is longer) and doesn't allow optimizers to inline the functions (as they are not visible to map_generic.c file).
So, how would you go about implementing something like this?
Note: I wrote the code in the stack-overflow question form, so excuse me if there are minor errors.
Side question: Anyone has a better idea for a suffix that says "this structure copies the data instead of the pointer"? I use c that says "copies", but there could be a much better word for it in English that I don't know about.
Update:
I have come up with a third solution. In this solution, only one version of the map is written, the one that keeps a copy of data (mapc). This version would use memcpy to copy data. The other map is an interface to this, taking void *key and void *data pointers and sending &key and &data to mapc so that the address they contain would be copied (using memcpy).
This solution has the downside that a normal pointer assignment is done by memcpy, but it completely solves the issue otherwise and is very clean.
Alternatively, one can only implement the map and use an extra vectorc with mapc which first copies the data to vector and then gives the address to a map. This has the side effect that deletion from mapc would either be substantially slower, or leave garbage (or require other structures to reuse the garbage).
Update 2:
I came to the conclusion that careless users might use my library the way they write C++, copy after copy after copy. Therefore, I am abandoning this idea and accepting only pointers.
You roughly covered both possible solutions.
The preprocessor macros roughly correspond to C++ templates and have the same advantages and disadvantages:
They are hard to read.
Complex macros are often hard to use (consider type safety of parameters etc.)
They are just "generators" of more code, so in the compiled output a lot of duplicity is still there.
On other side, they allow compiler to optimize a lot of stuff.
The function pointers roughly correspond to C++ polymorphism and they are IMHO cleaner and generally easier-to-use solution, but they bring some cost at runtime (for tight loops, few extra function calls can be expensive).
I generally prefer the function calls, unless the performance is really critical.
There's also a third option that you haven't considered: you can create an external script (written in another language) to generate your code from a series of templates. This is similar to the macro method, but you can use a language like Perl or Python to generate the code. Since these languages are more powerful than the C pre-processor, you can avoid some of the potential problems inherent in doing templates via macros. I have used this method in cases where I was tempted to use complex macros like in your example #1. In the end, it turned out to be less error-prone than using the C preprocessor. The downside is that between writing the generator script and updating the makefiles, it's a little more difficult to get set up initially (but IMO worth it in the end).
What you're looking for is polymorphism. C++, C# or other object oriented languages are more suitable to this task. Though many people have tried to implement polymorphic behavior in C.
The Code Project has some good articles/tutorials on the subject:
http://www.codeproject.com/Articles/10900/Polymorphism-in-C
http://www.codeproject.com/Articles/108830/Inheritance-and-Polymorphism-in-C

How do I implement callback functions in C?

gcc 4.4.3 c89
I am creating a client server application and I will need to implement some callback functions.
However, I am not too experienced in callbacks. And I am wondering if anyone knowns some good reference material to follow when designing callbacks. Is there any design patterns that are used for c. I did look at some patterns but there where all c++.
Many thanks for any suggestions,
Here is a very rough example. Please note, the only thing I'm trying to demonstrate is the use of callbacks, its designed to be informational, not a demonstration.
Lets say that we have a library (or any set of functions that revolve around a structure), we're going to have code that looks similar to this (of course, I'm naming it foo):
typedef struct foo {
int value;
char *text;
} foo_t;
That's simple enough. We'd then (conventionally) provide some means of allocating and freeing it, such as:
foo_t *foo_start(void)
{
foo_t *ret = NULL;
ret = (foo_t *)malloc(sizeof(struct foo));
if (ret == NULL)
return NULL;
return ret;
}
And then:
void foo_stop(foo_t *f)
{
if (f != NULL)
free(f);
}
But we want a callback, so we can define a function that will be entered when foo->text has something to report. To do that, we use a typed function pointer:
typedef void (* foo_callback_t)(int level, const char *data);
We also want any of the foo family of functions to be able to enter this callback conveniently. To do that, we need to add it to the structure, which would now look like this:
typedef struct foo {
int value;
char *text;
foo_callback_t callback;
} foo_t;
Then we write the function that will actually be entered (using the same prototype of our callback type):
void my_foo_callback(int val, char *data)
{
printf("Val is %d, data is %s\n", val, data == NULL ? "NULL" : data);
}
We then need to write some convenient way to say what function it actually points to:
void foo_reg_callback(foo_t *f, void *cbfunc)
{
f->callback = cbfunc;
}
And then our other foo functions can use it, for instance:
int foo_bar(foo_t *f, char *data)
{
if (data == NULL)
f->callback(LOG_ERROR, "data was NULL");
}
Note that in the above:
f->callback(LOG_ERROR, "data was NULL");
Is just like doing this:
my_foo_callback(LOG_ERROR, "data was NULL"):
Except that, we enter my_foo_callback() via a function pointer that we previously set, thereby giving us the flexibility to define our own handler on the fly (and even switch handlers if / as needed).
One of the biggest problems with callbacks (and even the code above) is type safety when using them. A lot of callbacks will take a void * pointer, usually named something like context which could be any type of data/memory. This provides great flexibility, but can be problematic if your pointers get away from you. For instance, you don't want to accidentally cast what is actually a struct * as char * (or int for that matter) by assignment. You can pass much more than simple strings and integers - structures, unions, enums, etc can all be passed. CCAN's type safe callbacks help you to avoid unwittingly evil casts (to / from void *) when doing so.
Again, this is an over simplified example that's designed to give you an overview of one possible way to use callbacks. Please consider it psuedo code that is meant only as an example.
IN C, callbacks are done with function pointers.
One feature that you definitely want is user defined context. Your code takes a void * pointer and makes it available to the callback function:
void callback(..., void *ctx);
void call_service_which_invokes_callback(...,
void (*cb)(..., void *ctx),
void *ctx);
This way, the callback can access any necessary state without having to use global variables.
Callbacks in C are implemented using function pointers. This might be helpful for starting points:
What is a "callback" in C and how are they implemented?
Also,
http://www.newty.de/fpt/callback.html#howto

Resources