问题
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 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.
回答1:
GLib has implementation of generic value types in form of GValue: http://library.gnome.org/devel/gobject/unstable/gobject-Generic-values.html
回答2:
Although I doubt that the original author still needs an answer (hopefully at least after 4 years), I wanted to add my 2ct.
First, let me state that the thing you ask for is called a sum-type and usually supported in functional languages (that is, it is rather a language design feature and not a library issue).
Second, it is highly doubtful that you will find a C-library for that case for the simple reason that any such library would support a fixed set of variants that probably does not fit your needs.
Howerver, for the sake of completeness, you might want to give msgpack a try.
回答3:
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.)
回答4:
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.
来源:https://stackoverflow.com/questions/2734808/variant-datatype-library-for-c