sorry to spam perl6-internals, but i'm answering a public question, and you may find something worth thinking about my description of the hoops i have to jump through... or maybe not. ignore if you like. i am quite open to suggestions how i should do this for perl6. replies off-list, please, as i'm not subscribed.


On Tuesday, October 28, 2003, at 12:24 AM, Anuradha Ratnaweera wrote:


I am not sure if this is the correct place to ask this, so please point
me to correct direction if it is not.

As far as I know, there is no "native" way of calling C/C++ libraries
from within Perl 5.

there's the built-in ioctl, and the DynaLoader docs point you to C::DynaLoader, but in general, yes, there's no practical way to call C functions without some glue.


When C/C++ API involves structures, the
corresponding Perl binding uses hashes, and an intermediate step
converts the hash to a structure, and call the C program with the
converted structure. An example of an elegent system which does this is
in gtk2-perl (http://gtk2-perl.sourceforge.net). Muppet, please correct
me if I am wrong here.

gtk2-perl is a little picky about how structures and objects are represented in Perl. there are two basic ways, which result in three things happening:


1. GObjects are reference-counted beings with sophisticated lifetime management. these get magical glue to Perl in the form of attaching magic (containing the object pointer) to the Perl object, and sharing references between the Perl and C objects to ensure that the combined object lives for the right amount of time. a side effect is that DESTROY may be called more than once, but the Perl object and C object are persistent. for convenience, we chose a hash reference as the object representation, because this allows Perl developers to store arbitrary data with the object without using the type-unsafe GObject data keys. i would like to have a way to tie the object data to hash keys, but tie and our object wrapper don't get along.

2. GBoxed is a nifty way for GLib-based libraries to assign copy and free functions to a type. these are used with opaque pointers, which are nearly 100% of the time plain old C structures. there is no instance of a GBoxed -- the type refers to the functions, and you're on your honor to ensure that you call the proper GBoxed functions on a given opaque pointer; this allows generic handling of black-box structures.

gtk2-perl handles GBoxed via another vtable layer called GPerlBoxedWrapperClass, which contains pointers to functions which wrap, unwrap, and destroy the boxed objects. This allows for two basic modes of handling:

a) as opaque types. default boxed wrapper class implements the Perl wrapper as a blessed scalar reference, containing the value of a pointer to a small wrapper structure which contains the boxed pointer and the type identifier. members are accessed via functions, and no data is duplicated.

b) as native perl types, via the wrap and unwrap functions. this does result in duplication of data, but we rationalize this in a few ways: i) it makes using the binding 1000 times easier (e.g. GnomeCanvasPoints), ii) the user must not modify the real data in the first place (one-way C-to-hash mappings for useful information structures).


Interfacing C/C++ libs this way involves creation of intermediate
structures that duplicates lots of data.

as mentioned above, we try to avoid duplication of data except when there are good reasons.


But if the structure of the structure _is_ known, then there is the
possibility of kind of "rearranging" the hashes and calling the C/C++
library without duplicating the related data to a seperate structure.

i seriously doubt anything like this is possible. however, given metadata that describes how each structure is laid out, you could implement something that packs and unpacks them for you. however, the runtime overhead of reading, processing, and/or storing those descriptions would be greater than the codespace overhead and time to run through specialized code for each structure (unless you had hundreds or thousands of them).


--
muppet <scott at asofyet dot org>



Reply via email to