[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ffi docs

From: Ludovic Courtès
Subject: Re: ffi docs
Date: Fri, 16 Apr 2010 10:43:28 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Hi Neil,

A few answers/comments and I’ll leave the rest to Andy.  ;-)

Neil Jerram <address@hidden> writes:

> Andy Wingo <address@hidden> writes:

>>  -- Scheme Procedure: dynamic-link [library]
>>  -- C Function: scm_dynamic_link (library)
> Code below implies that library can be omitted, and that this -
> i.e. '(dynamic-link)' - means to return an object representing libguile
> itself.  Should that be mentioned in the following doc?

This is actually documented:

>>      When LIBRARY is omitted, a "global symbol handle" is returned.
>>      This handle provides access to the symbols available to the
>>      program at run-time, including those exported by the program
>>      itself and the shared libraries already loaded.


>>    A compiled module should have a specially named "module init
>> function".  Guile knows about this special name and will call that
>> function automatically after having linked in the shared library.  For
>> our example, we replace `init_math_bessel' with the following code in
>> `bessel.c':
>>      void
>>      init_math_bessel (void *unused)
>>      {
>>        scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
>>        scm_c_export ("j0", NULL);
>>      }
>>      void
>>      scm_init_math_bessel_module ()
>>      {
>>        scm_c_define_module ("math bessel", init_math_bessel, NULL);
>>      }
>>    The general pattern for the name of a module init function is:
>> `scm_init_', followed by the name of the module where the individual
>> hierarchical components are concatenated with underscores, followed by
>> `_module'.
> Is this still correct?

The bit that says “Guile knows about this special name” has been
incorrect since 1.8 AFAIK, because the name of the init function has to
be explicitly given to ‘load-extension’.  So this part can be removed.

The bit about the “general pattern for the name” is correct, but it
should probably made clear that it’s just a convention.

>>    So when accessing a C value through a Scheme pointer, we must give
>> the type of the pointed-to value explicitly, as a parameter to any
>> Scheme procedure that accesses the value.
> This confused me at first.  I think I understand the point now, but
> - isn't it actually much more to do with the ELF binary format, rather
>   than with C?  If libguile could read and parse C, it would be able to
>   infer the type of any variable that the Scheme layer might request.
>   The problem is precisely that what we are linking with is *not* C
>   anymore...  It's just untyped pointers.

C itself is very weakly typed: about anything can be cast to anything

> - I think "give the type ... as a parameter to any Scheme procedure that
>   accesses the value" is misleading, because we don't do that!  Rather,
>   we construct a box that includes both the pointer and the type, and
>   then pass the box around.



>>    As an example, `(dynamic-pointer "foo" void bar-lib)' links in the
>> FOO symbol in the BAR-LIB library as a pointer to `void': a `void*'.
>>    Void pointers may be accessed as bytevectors.
>>  -- Scheme Procedure: foreign->bytevector foreign [uvec_type [offset
>>           [len]]]
>>  -- C Function: scm_foreign_to_bytevector foreign uvec_type offset len
>>      Return a bytevector aliasing the memory pointed to by FOREIGN.
>>      FOREIGN must be a void pointer, a foreign whose type is VOID. By
>>      default, the resulting bytevector will alias all of the memory
>>      pointed to by FOREIGN, from beginning to end, treated as a `vu8'
>>      array.
> It feels like we're missing a unification trick here.

What do you mean?

> Thought #1: if we have, e.g., an int8 pointer ip, why not just use
> (foreign-ref ip n) to interpret the pointer as pointing to an array, and
> get its nth element?
> Thought #2: but if we do that we'll be duplicating the bytevector API.
> So instead, shouldn't the fundamental operation be (foreign->bytevector
> NAME TYPE LIBRARY [LEN]), and get/set then done using the bytevector
> API?

What would be LIBRARY here?

FWIW I’m fine with this procedure.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]