views:

197

answers:

3

Is there a decent open-source C library for storing and manipulating
dynamically-typed variables (a.k.a. variants)? I'm primarily interested in atomic values (int8, int16, int32, uint, strings, blobs, etc.), while JSON-style arrays and objects as well as custom objects would also be nice. A major case where such a library would be useful is in working with SQL databases.

The most obvious feature of such a library would be a single type for all supported values, e.g.:

struct Variant {
    enum Type type;
    union {
        int8_t int8_;
        int16_t int16_;
        // ...
    };
};

Other features might include converting Variant objects to/from C structures (using a binding table), converting values to/from strings, and integration with an existing database library such as SQLite.

Note: I do not believe this is question is a duplicate of http://stackoverflow.com/questions/649649/any-library-for-generic-datatypes-in-c , which refers to "queues, trees, maps, lists". What I'm talking about focuses more on making working with SQL databases roughly as smooth as working with them in interpreted languages.

A: 

C is a very strong typed language, variants are not part of its philosophy. An union can't be a solution because you still have to choose the data type you want to use, it's typically used to store color codes on int and char[4].

If you look at the C-SQLite interface, this function is provided :

int sqlite_step(
  sqlite_vm *pVm,          /* The virtual machine to execute */
  int *pN,                 /* OUT: Number of columns in result */
  const char ***pazValue,  /* OUT: Column data */
  const char ***pazColName /* OUT: Column names and datatypes */
);

Data types are represented by char* and it's the developer's task to figure how to get types from these. I think any kind of variant type would have been better but it's just not C. C does not implement variants and is not meant to.

Opera
C is *statically* typed, but not "very" strongly typed.
KennyTM
No strong typing. Once you introduce casting to and from void* you make a hole in the type checking system. C is definitely NOT strong typed.
Hernán
A: 

I suggest reading the manual on the SQL database connector. The MySQL connector provides an API for obtaining the field types in the result.

You could create a Factory function that fills a structure based on the field type. Ironically, since C doesn't have Base types, you'll have to use a void * pointer and recast to the known structure type. (Even though void * is the type you are trying to get rid of.)

Thomas Matthews
I did something similar to this by creating a binding system which sets variables referenced by `void *` pointers. I'm not afraid of `void *`, I just want a simple framework to work with dynamic types in C.
Joey Adams
+1  A: 

GLib has implementation of generic value types in form of GValue: http://library.gnome.org/devel/gobject/unstable/gobject-Generic-values.html

el.pescado