Submitted by Vince (Mon Apr 10 21:07:41 UTC 2006)
For instance, a class doing some mathematical computations could rely heavily on few internals of an extension for manipulating vectors of numbers.
It is for now really difficult to do that in a way that is platform dependent: as it is really easy to do that under Linux, and reasonably easy to do that under MacOS (X), it comes much more difficult under Win32, as the dynamic linker doesn't behave at all like in the two others.
rb_export_symbol(module, "symbol", &symbol);
And another one based on the first could make use of the function with the simple following code:
symbol = rb_import_symbol(module, "symbol");
These two functions simply provide a C-level access returning the right types to a class/module hash which could be called for instance @@_exported_C_symbols.
This is a transparent change, as only the extensions which will make use of this system will have a special meaning of the variable @@_exported_C_symbols.
Moreover, the code is really light and shouldn't be a burden on any architecture, while it will definitely provide a great speed improvement for certain extensions.
#define MV_SYMBOLS "@@_exported_C_symbols" /* makes sure that the hash is registered for the given module and returns it */ static VALUE get_symbol_hash(VALUE module) { VALUE hash = rb_iv_get(module, MV_SYMBOLS); if(NIL_P(hash)) { /* Then, we create it */ hash = rb_hash_new(); rb_iv_set(module, MV_SYMBOLS, hash); return hash; } else { Check_Type(hash, T_HASH); return hash; } } /* registers a symbol in the given module.*/ void rb_export_symbol(VALUE module, const char * symbol_name, void * symbol) { VALUE hash = get_symbol_hash(module); rb_hash_aset(hash, rb_str_new2(symbol_name), INT2NUM((int) symbol)); } void * rb_import_symbol(VALUE module, const char * symbol_name) { VALUE hash = rb_iv_get(module, MV_SYMBOLS); if(TYPE(hash) != T_HASH) return NULL; /* doesn't fail, but the importing module should definitely check the return value. Beware of segfaults ! */ VALUE symbol = rb_hash_aref(hash, rb_str_new2(symbol_name)); if(TYPE(symbol) == T_FIXNUM || TYPE(symbol) == T_BIGNUM) return (void *) NUM2INT(symbol); return NULL; }
You can also find some (simple) examples of use in that repository.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .