Commits

Armin Rigo committed abacd60

ffi.include().

Comments (0)

Files changed (4)

         ctypeptr = self._pointer_to(ctype)
         return self._backend.rawaddressof(ctypeptr, cdata, offset)
 
+    def include(self, ffi_to_include):
+        """Includes the typedefs, structs, unions and enums defined
+        in another FFI instance.  Usage is similar to a #include in C,
+        where a part of the program might include types defined in
+        another part for its own usage.  Note that the include()
+        method has no effect on functions, constants and global
+        variables, which must anyway be accessed directly from the
+        lib object returned by the original FFI instance.
+        """
+        self._parser.include(ffi_to_include._parser)
+
 
 def _make_ffi_library(ffi, libname, flags):
     import os
         else:   # opaque enum
             tp = model.EnumType(explicit_name, (), ())
         return tp
+
+    def include(self, other):
+        for name, tp in other._declarations.items():
+            kind = name.split(' ', 1)[0]
+            if kind in ('typedef', 'struct', 'union', 'enum'):
+                self._declare(name, tp)

doc/source/index.rst

 Misc methods on ffi
 -------------------
 
+``ffi.include(other_ffi)``: includes the typedefs, structs, unions and
+enums defined in another FFI instance.  Usage is similar to a
+``#include`` in C, where a part of the program might include types
+defined in another part for its own usage.  Note that the include()
+method has no effect on functions, constants and global variables, which
+must anyway be accessed directly from the ``lib`` object returned by the
+original FFI instance.  *New in version 0.5.*
+
+.. "versionadded:: 0.5" --- inlined in the previous paragraph
+
 ``ffi.errno``: the value of ``errno`` received from the most recent C call
 in this thread, and passed to the following C call, is available via
 reads and writes of the property ``ffi.errno``.  On Windows we also save

testing/backend_tests.py

         assert foo1.x == 10
         assert foo2.y == 20
         assert foo2.z == 30
+
+    def test_missing_include(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("typedef signed char schar_t;")
+        py.test.raises((AttributeError, TypeError), ffi2.cast, "schar_t", 142)
+
+    def test_include_typedef(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("typedef signed char schar_t;")
+        ffi2.include(ffi1)
+        p = ffi2.cast("schar_t", 142)
+        assert int(p) == 142 - 256
+
+    def test_include_struct(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("struct foo { int x; };")
+        ffi2.include(ffi1)
+        p = ffi2.new("struct foo *", [142])
+        assert p.x == 142
+
+    def test_include_union(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("union foo { int x; };")
+        ffi2.include(ffi1)
+        p = ffi2.new("union foo *", [142])
+        assert p.x == 142
+
+    def test_include_enum(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("enum foo { FA, FB, FC };")
+        ffi2.include(ffi1)
+        p = ffi2.cast("enum foo", 1)
+        assert ffi2.string(p) == "FB"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.