[erlang-questions] Erlang FFI: 1st discussion summary

Martin Bjorklund mbj@REDACTED
Fri Sep 14 11:29:56 CEST 2007


Hi,


Alceste Scalas <alceste@REDACTED> wrote:

>     --------------------------------------------------
>     1.1. Getting information about preloaded functions
>     --------------------------------------------------
> 
>     The proposed high-level ffi:call/3 would need information about
>     functions and FFI signatures preloaded with
>     erl_ddll:load_library/3.  This information could be useful for
>     developers, too (e.g. for debugging pourposes).  For these
>     reasons, the erl_ddll:info/2 BIF could be extended with a
>     'preloads' argument, that would return a list of preloaded
>     functions, signatures etc.  This information could be obtained
>     via erl_ddll:info/1 and erl_ddll:info/0 as well.

This seems very useful.

> ======================================================
> 2. Creating Erlang binaries from C strings and buffers
> ======================================================
> 
> The first proposal on this issue [5] can be revised considering type
> tagging.  A new 'cstring' type atom/tag can be introduced, in order
> to distinguish NULL-terminated C strings from generic 'pointer's to
> byte buffers.  Two functions could be used for turning them into
> Erlang binaries:
> 
>     ffi:cstring_to_binary(TaggedCString) -> binary()
>         TaggedCString = {cstring, CStringPtr}
>         CStringPtr = integer()
> 
>         Return a new binary with a copy of the given NULL-terminated
>         C string (including the trailing \0);
> 
>     ffi:buffer_to_binary(TaggedPointer, Size) -> binary()
>         TaggedPointer = {pointer, Ptr}
>         Ptr = integer()
> 
>         Return a new binary filled with a copy of Size bytes read
>         from the given C pointer.
> 
> These two functions would have, as seen in the previous section,
> their type-untagged equivalents: ffi:raw_cstring_to_binary/1 and
> ffi:raw_buffer_to_binary/2.

In this case, I don't think the tagging gives you anything.

Another thing that would be nice would be to be able to get to a
ref-counted binary in the C-code; i.e. let the C-code inc the ref
count if it wants to.  This would save a copy when the binary is very
big.


> ==================================
> 3. Determining the size of C types
> ==================================
> 
> The sizes of C types could be determined in run-time with a new
> ffi:sizeof/1 BIF (initially proposed in [6]):
> 
>       * ffi:sizeof(CType) -> integer()
>             CType = type_tag()
> 
>             Return the number of bytes used by CType on the current
>             platform.
> 
> Type size information should, in general, *not* be hardcoded,
> because it may change when running the same BEAM files on different
> architectures.  The BIF above is the recommended way for getting
> type sizes when writing portable code.
> 
> However, when the FFI-based code is *not* expected to be portable
> without recompilation, the size of C types remains constant and
> could be determined when the Erlang/OTP sources are compiled.  Thus,
> this information could be stored in a .hrl file.  Developers could
> -include_lib("kernel/include/ffi_hardcodes.hrl") [7] and obtain a
> set of faster and easier-to-use macros, for each supported FFI type:
> 
>     FFI_HARDCODED_SIZEOF_<TYPE>
>         The type size in bytes
> 
>     FFI_HARDCODED_<TYPE>_BITS
>         The type size in bits
> 
> The size in bits is precomputed in order to simplify binary
> matching, since expressions like (?FFI_HARDCODED_SIZEOF_LONG * 8)
> are not allowed in patterns.

I think both these suggestions makes sense.  For the use case I have
in mind (which currently is implemented as a driver), I would use the
hardcoded constants.



/martin



More information about the erlang-questions mailing list