File: rffi.rst

package info (click to toggle)
pypy 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 107,216 kB
  • sloc: python: 1,201,787; ansic: 62,419; asm: 5,169; cpp: 3,017; sh: 2,534; makefile: 545; xml: 243; lisp: 45; awk: 4
file content (67 lines) | stat: -rw-r--r-- 2,356 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.. _rffi:

Foreign Function Interface for RPython
======================================

Purpose
-------

This document describes an FFI for the RPython language, concentrating
on low-level backends like C. It describes
how to declare and call low-level (C) functions from RPython level.


Declaring low-level external function
-------------------------------------

Declaring external C function in RPython is easy, but one needs to
remember that low level functions eat :ref:`low level types <low-level-types>` (like
lltype.Signed or lltype.Array) and memory management must be done
by hand. To declare a function, we write::

  from rpython.rtyper.lltypesystem import rffi

  external_function = rffi.llexternal(name, args, result)

where:

* name - a C-level name of a function (how it would be rendered)
* args - low level types of args
* result - low level type of a result

You can pass in additional information about C-level includes,
libraries and sources by passing in the optional ``compilation_info``
parameter::

  from rpython.rtyper.lltypesystem import rffi
  from rpython.translator.tool.cbuild import ExternalCompilationInfo

  info = ExternalCompilationInfo(includes=[], libraries=[])

  external_function = rffi.llexternal(
    name, args, result, compilation_info=info
    )

See :source:`cbuild <rpython/translator/tool/cbuild.py>` for more info on ExternalCompilationInfo.


Types
-----

In :source:`rffi <rpython/rtyper/lltypesystem/rffi.py>` there are various declared types for C-structures, like CCHARP
(char*), SIZE_T (size_t) and others. Refer to file for details. 
Instances of non-primitive types must be alloced by hand, with call 
to lltype.malloc, and freed by lltype.free both with keyword argument 
flavor='raw'. There are several helpers like string -> char*
converter, refer to the source for details.


Registering function as external
--------------------------------

Once we provided low-level implementation of an external function,
would be nice to wrap call to some library function (like os.open)
with such a call. For this, there is a `register_external` routine,
located in :source:`extfunc.py <rpython/rtyper/extfunc.py>`, which provides nice API for declaring such a
functions, passing llimpl as an argument and eventually llfakeimpl
as a fake low-level implementation for tests performed by an llinterp.