Пример #1
0
def try_compile_cache(c_files, eci):
    "Try to compile a program; caches the result (starts with 'True' or 'FAIL')"
    # Import 'platform' every time, the compiler may have been changed
    from pypy.translator.platform import platform
    path = cache_file_path(c_files, eci, 'try_compile_cache')
    try:
        data = path.read()
    except py.error.Error:
        data = ''
    if not (data.startswith('True') or data.startswith('FAIL\n')):
        try:
            _previous = platform.log_errors
            try:
                platform.log_errors = False
                platform.compile(c_files, eci)
            finally:
                del platform.log_errors
                # ^^^remove from the instance --- needed so that it can
                # compare equal to another instance without it
                if platform.log_errors != _previous:
                    platform.log_errors = _previous
            data = 'True'
            path.write(data)
        except CompilationError, e:
            data = 'FAIL\n%s\n' % (e, )
Пример #2
0
def try_compile_cache(c_files, eci):
    "Try to compile a program; caches the result (starts with 'True' or 'FAIL')"
    # Import 'platform' every time, the compiler may have been changed
    from pypy.translator.platform import platform

    path = cache_file_path(c_files, eci, "try_compile_cache")
    try:
        data = path.read()
    except py.error.Error:
        data = ""
    if not (data.startswith("True") or data.startswith("FAIL\n")):
        try:
            _previous = platform.log_errors
            try:
                platform.log_errors = False
                platform.compile(c_files, eci)
            finally:
                del platform.log_errors
                # ^^^remove from the instance --- needed so that it can
                # compare equal to another instance without it
                if platform.log_errors != _previous:
                    platform.log_errors = _previous
            data = "True"
            path.write(data)
        except CompilationError, e:
            data = "FAIL\n%s\n" % (e,)
Пример #3
0
def try_compile_cache(c_files, eci):
    path = cache_file_path(c_files, eci, 'try_compile_cache')
    try:
        data = path.read()
    except py.error.Error:
        data = ''
    if not (data.startswith('True') or data.startswith('FAIL\n')):
        try:
            platform.compile(c_files, eci)
            data = 'True'
        except CompilationError, e:
            data = 'FAIL\n%s\n' % (e,)
        path.write(data)
Пример #4
0
    def prepare_c_example(cls):
        from pypy.tool.udir import udir
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform

        c_file = udir.ensure("test__ffi", dir=1).join("foolib.c")
        # automatically collect the C source from the docstrings of the tests
        snippets = [
            """
        #ifdef _WIN32
        #define DLLEXPORT __declspec(dllexport)
        #else
        #define DLLEXPORT
        #endif
        """
        ]
        for name in dir(cls):
            if name.startswith('test_'):
                meth = getattr(cls, name)
                # the heuristic to determine it it's really C code could be
                # improved: so far we just check that there is a '{' :-)
                if meth.__doc__ is not None and '{' in meth.__doc__:
                    snippets.append(meth.__doc__)
        #
        c_file.write(py.code.Source('\n'.join(snippets)))
        eci = ExternalCompilationInfo(export_symbols=[])
        return str(platform.compile([c_file], eci, 'x', standalone=False))
Пример #5
0
    def test_cdll_life_time(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        long fun(long i) {
            return i + 42;
        }
        '''))
        eci = ExternalCompilationInfo(export_symbols=['fun'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)
        slong = cast_type_to_ffitype(rffi.LONG)
        fun = lib.getrawpointer('fun', [slong], slong)
        del lib  # already delete here

        buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw')
        buffer[0] = 200
        buffer[1] = -1
        fun.call([rffi.cast(rffi.VOIDP, buffer)],
                 rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
        assert buffer[1] == 242

        lltype.free(buffer, flavor='raw')
        del fun

        assert not ALLOCATED
Пример #6
0
    def setup_class(cls):
        from pypy.tool.udir import udir
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.tool.cbuild import STANDARD_DEFINES
        from pypy.translator.platform import platform

        BaseFfiTest.setup_class()
        # prepare C code as an example, so we can load it and call
        # it via rlib.libffi
        c_file = udir.ensure("test_libffi", dir=1).join("foolib.c")
        # automatically collect the C source from the docstrings of the tests
        snippets = []
        exports = []
        for name in dir(cls):
            if name.startswith('test_'):
                meth = getattr(cls, name)
                # the heuristic to determine it it's really C code could be
                # improved: so far we just check that there is a '{' :-)
                if meth.__doc__ is not None and '{' in meth.__doc__:
                    snippets.append(meth.__doc__)
                    import re
                    for match in re.finditer(" ([a-z_]+)\(", meth.__doc__):
                        exports.append(match.group(1))
        #
        c_file.write(STANDARD_DEFINES +
                     str(py.code.Source('\n'.join(snippets))))
        eci = ExternalCompilationInfo(export_symbols=exports)
        cls.libfoo_name = str(
            platform.compile([c_file], eci, 'x', standalone=False))
        cls.dll = cls.CDLL(cls.libfoo_name)
Пример #7
0
    def test_cdll_life_time(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source(
                """
        long fun(long i) {
            return i + 42;
        }
        """
            )
        )
        eci = ExternalCompilationInfo(export_symbols=["fun"])
        lib_name = str(platform.compile([c_file], eci, "x", standalone=False))

        lib = CDLL(lib_name)
        slong = cast_type_to_ffitype(rffi.LONG)
        fun = lib.getrawpointer("fun", [slong], slong)
        del lib  # already delete here

        buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor="raw")
        buffer[0] = 200
        buffer[1] = -1
        fun.call([rffi.cast(rffi.VOIDP, buffer)], rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
        assert buffer[1] == 242

        lltype.free(buffer, flavor="raw")
        del fun

        assert not ALLOCATED
Пример #8
0
    def prepare_c_example(cls):
        from pypy.tool.udir import udir
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform

        c_file = udir.ensure("test__ffi", dir=1).join("foolib.c")
        # automatically collect the C source from the docstrings of the tests
        snippets = ["""
        #ifdef _WIN32
        #define DLLEXPORT __declspec(dllexport)
        #else
        #define DLLEXPORT
        #endif
        """]
        for name in dir(cls):
            if name.startswith('test_'):
                meth = getattr(cls, name)
                # the heuristic to determine it it's really C code could be
                # improved: so far we just check that there is a '{' :-)
                if meth.__doc__ is not None and '{' in meth.__doc__:
                    snippets.append(meth.__doc__)
        #
        c_file.write(py.code.Source('\n'.join(snippets)))
        eci = ExternalCompilationInfo(export_symbols=[])
        return str(platform.compile([c_file], eci, 'x', standalone=False))
Пример #9
0
    def setup_class(cls):
        from pypy.tool.udir import udir
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform

        BaseFfiTest.setup_class()
        # prepare C code as an example, so we can load it and call
        # it via rlib.libffi
        c_file = udir.ensure("test_libffi", dir=1).join("foolib.c")
        # automatically collect the C source from the docstrings of the tests
        snippets = []
        exports = []
        for name in dir(cls):
            if name.startswith('test_'):
                meth = getattr(cls, name)
                # the heuristic to determine it it's really C code could be
                # improved: so far we just check that there is a '{' :-)
                if meth.__doc__ is not None and '{' in meth.__doc__:
                    snippets.append(meth.__doc__)
                    import re
                    for match in re.finditer(" ([a-z_]+)\(", meth.__doc__):
                        exports.append(match.group(1))
        #
        c_file.write(py.code.Source('\n'.join(snippets)))
        eci = ExternalCompilationInfo(export_symbols=exports)
        cls.libfoo_name = str(platform.compile([c_file], eci, 'x',
                                               standalone=False))
Пример #10
0
def build_executable_cache(c_files, eci):
    path = cache_file_path(c_files, eci, 'build_executable_cache')
    try:
        return path.read()
    except py.error.Error:
        result = platform.execute(platform.compile(c_files, eci))
        path.write(result.out)
        return result.out
Пример #11
0
    def test_struct_by_val(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source(
                """
        #include <stdlib.h>
        #include <stdio.h>

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        long sum_x_y_p(struct x_y *p) {
            return p->x + p->y;
        }
        
        """
            )
        )
        eci = ExternalCompilationInfo(export_symbols=["sum_x_y"])
        lib_name = str(platform.compile([c_file], eci, "x", standalone=False))

        lib = CDLL(lib_name)

        slong = cast_type_to_ffitype(rffi.LONG)
        size = slong.c_size * 2
        alignment = slong.c_alignment
        tpe = make_struct_ffitype_e(size, alignment, [slong, slong])

        sum_x_y = lib.getrawpointer("sum_x_y", [tpe.ffistruct], slong)

        buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor="raw")
        buffer[0] = 200
        buffer[1] = 220
        buffer[2] = 666
        sum_x_y.call([rffi.cast(rffi.VOIDP, buffer)], rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 2)))
        assert buffer[2] == 420

        lltype.free(buffer, flavor="raw")
        del sum_x_y
        lltype.free(tpe, flavor="raw")
        del lib

        assert not ALLOCATED
Пример #12
0
def build_executable_cache(c_files, eci):
    "Builds and run a program; caches the result"
    # Import 'platform' every time, the compiler may have been changed
    from pypy.translator.platform import platform

    path = cache_file_path(c_files, eci, "build_executable_cache")
    try:
        return path.read()
    except py.error.Error:
        result = platform.execute(platform.compile(c_files, eci))
        path.write(result.out)
        return result.out
Пример #13
0
    def test_struct_by_val(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        long sum_x_y_p(struct x_y *p) {
            return p->x + p->y;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['sum_x_y'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        slong = cast_type_to_ffitype(rffi.LONG)
        size = slong.c_size * 2
        alignment = slong.c_alignment
        tpe = make_struct_ffitype_e(size, alignment, [slong, slong])

        sum_x_y = lib.getrawpointer('sum_x_y', [tpe.ffistruct], slong)

        buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw')
        buffer[0] = 200
        buffer[1] = 220
        buffer[2] = 666
        sum_x_y.call([rffi.cast(rffi.VOIDP, buffer)],
                     rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 2)))
        assert buffer[2] == 420

        lltype.free(buffer, flavor='raw')
        del sum_x_y
        lltype.free(tpe, flavor='raw')
        del lib

        assert not ALLOCATED
Пример #14
0
def compile_so_file():
    from pypy.translator.platform import platform
    from pypy.translator.tool.cbuild import ExternalCompilationInfo
    udir = py.test.ensuretemp('_ctypes_test')
    cfile = py.magic.autopath().dirpath().join("_ctypes_test.c")

    if sys.platform == 'win32':
        libraries = ['oleaut32']
    else:
        libraries = []
    eci = ExternalCompilationInfo(libraries=libraries)

    return platform.compile([cfile], eci, str(udir.join('_ctypes_test')),
                            standalone=False)
Пример #15
0
    def test_lib_on_libpaths(self):
        from pypy.translator.platform import platform
        from pypy.translator.tool.cbuild import ExternalCompilationInfo

        tmpdir = udir.join('lib_on_libppaths')
        tmpdir.ensure(dir=1)
        c_file = tmpdir.join('c_file.c')
        c_file.write('int f(int a, int b) { return (a + b); }')
        eci = ExternalCompilationInfo(export_symbols=['f'])
        so = platform.compile([c_file], eci, standalone=False)
        eci = ExternalCompilationInfo(libraries=['c_file'],
                                      library_dirs=[str(so.dirpath())])
        f = rffi.llexternal('f', [rffi.INT, rffi.INT],
                            rffi.INT,
                            compilation_info=eci)
        assert f(3, 4) == 7
Пример #16
0
def compile_so_file():
    from pypy.translator.platform import platform
    from pypy.translator.tool.cbuild import ExternalCompilationInfo
    udir = py.test.ensuretemp('_ctypes_test')
    cfile = py.magic.autopath().dirpath().join("_ctypes_test.c")

    if sys.platform == 'win32':
        libraries = ['oleaut32']
    else:
        libraries = []
    eci = ExternalCompilationInfo(libraries=libraries)

    return platform.compile([cfile],
                            eci,
                            str(udir.join('_ctypes_test')),
                            standalone=False)
Пример #17
0
    def test_lib_on_libpaths(self):
        from pypy.translator.platform import platform

        tmpdir = udir.join('lib_on_libppaths')
        tmpdir.ensure(dir=1)
        c_file = tmpdir.join('c_file.c')
        c_file.write('int f(int a, int b) { return (a + b); }')
        eci = ExternalCompilationInfo(export_symbols=['f'])
        so = platform.compile([c_file], eci, standalone=False)
        eci = ExternalCompilationInfo(
            libraries = ['c_file'],
            library_dirs = [str(so.dirpath())]
        )
        f = rffi.llexternal('f', [rffi.INT, rffi.INT], rffi.INT,
                            compilation_info=eci)
        assert f(3, 4) == 7
Пример #18
0
def test_external_lib():
    # XXX this one seems to be a bit too platform-specific. Check
    #     how to test it on windows correctly (using so_prefix?)
    #     and what are alternatives to LD_LIBRARY_PATH
    eci = ExternalCompilationInfo()
    c_source = """
    int f(int a, int b)
    {
        return (a + b);
    }
    """
    tmpdir = udir.join("external_lib").ensure(dir=1)
    c_file = tmpdir.join("libc_lib.c")
    c_file.write(c_source)
    l = platform.compile([c_file], eci, standalone=False)
    eci = ExternalCompilationInfo(libraries=["c_lib"], library_dirs=[str(tmpdir)])
    rffi_platform.verify_eci(eci)
Пример #19
0
def test_external_lib():
    # XXX this one seems to be a bit too platform-specific. Check
    #     how to test it on windows correctly (using so_prefix?)
    #     and what are alternatives to LD_LIBRARY_PATH
    eci = ExternalCompilationInfo()
    c_source = """
    int f(int a, int b)
    {
        return (a + b);
    }
    """
    tmpdir = udir.join('external_lib').ensure(dir=1)
    c_file = tmpdir.join('libc_lib.c')
    c_file.write(c_source)
    l = platform.compile([c_file], eci, standalone=False)
    eci = ExternalCompilationInfo(libraries=['c_lib'],
                                  library_dirs=[str(tmpdir)])
    rffi_platform.verify_eci(eci)
Пример #20
0
def build_executable_cache(c_files, eci, ignore_errors=False):
    "Builds and run a program; caches the result"
    # Import 'platform' every time, the compiler may have been changed
    from pypy.translator.platform import platform
    path = cache_file_path(c_files, eci, 'build_executable_cache')
    try:
        return path.read()
    except py.error.Error:
        _previous = platform.log_errors
        try:
            if ignore_errors:
                platform.log_errors = False
            result = platform.execute(platform.compile(c_files, eci))
        finally:
            if ignore_errors:
                del platform.log_errors
            # ^^^remove from the instance --- needed so that it can
            # compare equal to another instance without it
            if platform.log_errors != _previous:
                platform.log_errors = _previous
        path.write(result.out)
        return result.out
Пример #21
0
def build_executable_cache(c_files, eci, ignore_errors=False):
    "Builds and run a program; caches the result"
    # Import 'platform' every time, the compiler may have been changed
    from pypy.translator.platform import platform
    path = cache_file_path(c_files, eci, 'build_executable_cache')
    try:
        return path.read()
    except py.error.Error:
        _previous = platform.log_errors
        try:
            if ignore_errors:
                platform.log_errors = False
            result = platform.execute(platform.compile(c_files, eci))
        finally:
            if ignore_errors:
                del platform.log_errors
            # ^^^remove from the instance --- needed so that it can
            # compare equal to another instance without it
            if platform.log_errors != _previous:
                platform.log_errors = _previous
        path.write(result.out)
        return result.out
Пример #22
0
    def test_prefix(self):

        if sys.platform != 'linux2':
            py.test.skip("Not supported")

        from pypy.translator.platform import platform
        from pypy.translator.tool.cbuild import ExternalCompilationInfo

        tmpdir = udir.join('lib_on_libppaths_prefix')
        tmpdir.ensure(dir=1)
        c_file = tmpdir.join('c_file.c')
        c_file.write('int f(int a, int b) { return (a + b); }')
        eci = ExternalCompilationInfo()
        so = platform.compile([c_file], eci, standalone=False)
        sopath = py.path.local(so)
        sopath.move(sopath.dirpath().join('libc_file.so'))
        eci = ExternalCompilationInfo(libraries=['c_file'],
                                      library_dirs=[str(so.dirpath())])
        f = rffi.llexternal('f', [rffi.INT, rffi.INT],
                            rffi.INT,
                            compilation_info=eci)
        assert f(3, 4) == 7
Пример #23
0
    def setup_class(cls):
        import ctypes
        from pypy.tool.udir import udir
        from pypy.translator.platform import platform
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        
        c_source = """
        void *int_to_void_p(int arg) {}

        struct random_strucutre {
          int one;
          int *two;
        };

        struct random_structure* int_int_to_struct_p(int one, int two) {}
        """

        c_file = udir.join('rffilib.c')
        c_file.write(c_source)
        libname = platform.compile([c_file], ExternalCompilationInfo(),
                                   standalone=False)
        cls.lib = ctypes.CDLL(str(libname))
Пример #24
0
    def test_prefix(self):

        if sys.platform != 'linux2':
            py.test.skip("Not supported")

        from pypy.translator.platform import platform

        tmpdir = udir.join('lib_on_libppaths_prefix')
        tmpdir.ensure(dir=1)
        c_file = tmpdir.join('c_file.c')
        c_file.write('int f(int a, int b) { return (a + b); }')
        eci = ExternalCompilationInfo()
        so = platform.compile([c_file], eci, standalone=False)
        sopath = py.path.local(so)
        sopath.move(sopath.dirpath().join('libc_file.so'))
        eci = ExternalCompilationInfo(
            libraries = ['c_file'],
            library_dirs = [str(so.dirpath())]
        )
        f = rffi.llexternal('f', [rffi.INT, rffi.INT], rffi.INT,
                            compilation_info=eci)
        assert f(3, 4) == 7
Пример #25
0
    def setup_class(cls):
        import ctypes
        from pypy.tool.udir import udir
        from pypy.translator.platform import platform
        from pypy.translator.tool.cbuild import ExternalCompilationInfo

        c_source = """
        void *int_to_void_p(int arg) {}

        struct random_strucutre {
          int one;
          int *two;
        };

        struct random_structure* int_int_to_struct_p(int one, int two) {}
        """

        c_file = udir.join('rffilib.c')
        c_file.write(c_source)
        libname = platform.compile([c_file],
                                   ExternalCompilationInfo(),
                                   standalone=False)
        cls.lib = ctypes.CDLL(str(libname))
Пример #26
0
    def prepare_c_example():
        from pypy.tool.udir import udir
        c_file = udir.ensure("test__rawffi", dir=1).join("xlib.c")
        c_file.write(py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct x
        {
           int x1;
           short x2;
           char x3;
           struct x* next;
        };

        void nothing()
        {
        }

        char inner_struct_elem(struct x *x1)
        {
           return x1->next->x3;
        }

        struct x* create_double_struct()
        {
           struct x* x1, *x2;

           x1 = (struct x*)malloc(sizeof(struct x));
           x2 = (struct x*)malloc(sizeof(struct x));
           x1->next = x2;
           x2->x2 = 3;
           return x1;
        }

        void free_double_struct(struct x* x1)
        {
            free(x1->next);
            free(x1);
        }
        
        const char *static_str = "xxxxxx";
        const long static_int = 42;
        const double static_double = 42.42;
        
        unsigned short add_shorts(short one, short two)
        {
           return one + two;
        }

        void* get_raw_pointer()
        {
           return (void*)add_shorts;
        }

        char get_char(char* s, unsigned short num)
        {
           return s[num];
        }

        char *char_check(char x, char y)
        {
           if (y == static_str[0])
              return static_str;
           return NULL;
        }

        int get_array_elem(int* stuff, int num)
        {
           return stuff[num];
        }

        struct x* get_array_elem_s(struct x** array, int num)
        {
           return array[num];
        }

        long long some_huge_value()
        {
           return 1LL<<42;
        }

        unsigned long long some_huge_uvalue()
        {
           return 1LL<<42;
        }

        long long pass_ll(long long x)
        {
           return x;
        }

        static int prebuilt_array1[] = {3};

        int* allocate_array()
        {
            return prebuilt_array1;
        }

        long long runcallback(long long(*callback)())
        {
            return callback();
        }

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }

        int AAA_first_ordinal_function()
        {
            return 42;
        }
        
        '''))
        symbols = """get_char char_check get_raw_pointer
                     add_shorts
                     inner_struct_elem create_double_struct free_double_struct
                     get_array_elem get_array_elem_s
                     nothing
                     some_huge_value some_huge_uvalue pass_ll
                     runcallback
                     allocate_array
                     static_int static_double
                     sum_x_y
                     give perturb
                     AAA_first_ordinal_function
                  """.split()
        eci = ExternalCompilationInfo(export_symbols=symbols)
        return str(platform.compile([c_file], eci, 'x', standalone=False))
Пример #27
0
    def test_ret_struct_val(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['give', 'perturb'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        size = ffi_type_sshort.c_size * 2
        alignment = ffi_type_sshort.c_alignment
        tpe = make_struct_ffitype_e(size, alignment, [ffi_type_sshort] * 2)

        give = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort],
                                 tpe.ffistruct)
        inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')
        inbuffer[0] = rffi.cast(rffi.SHORT, 40)
        inbuffer[1] = rffi.cast(rffi.SHORT, 72)

        outbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')

        give.call([
            rffi.cast(rffi.VOIDP, inbuffer),
            rffi.cast(rffi.VOIDP, rffi.ptradd(inbuffer, 1))
        ], rffi.cast(rffi.VOIDP, outbuffer))

        assert outbuffer[0] == 40
        assert outbuffer[1] == 72

        perturb = lib.getrawpointer('perturb', [tpe.ffistruct], tpe.ffistruct)

        inbuffer[0] = rffi.cast(rffi.SHORT, 7)
        inbuffer[1] = rffi.cast(rffi.SHORT, 11)

        perturb.call([rffi.cast(rffi.VOIDP, inbuffer)],
                     rffi.cast(rffi.VOIDP, outbuffer))

        assert inbuffer[0] == 7
        assert inbuffer[1] == 11

        assert outbuffer[0] == 14
        assert outbuffer[1] == 33

        lltype.free(outbuffer, flavor='raw')
        lltype.free(inbuffer, flavor='raw')
        del give
        del perturb
        lltype.free(tpe, flavor='raw')
        del lib

        assert not ALLOCATED
Пример #28
0
    def prepare_c_example():
        from pypy.tool.udir import udir
        c_file = udir.ensure("test__rawffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct x
        {
           int x1;
           short x2;
           char x3;
           struct x* next;
        };

        void nothing()
        {
        }

        char inner_struct_elem(struct x *x1)
        {
           return x1->next->x3;
        }

        struct x* create_double_struct()
        {
           struct x* x1, *x2;

           x1 = (struct x*)malloc(sizeof(struct x));
           x2 = (struct x*)malloc(sizeof(struct x));
           x1->next = x2;
           x2->x2 = 3;
           return x1;
        }

        void free_double_struct(struct x* x1)
        {
            free(x1->next);
            free(x1);
        }
        
        const char *static_str = "xxxxxx";
        long static_int = 42;
        double static_double = 42.42;
        long double static_longdouble = 42.42;
        
        unsigned short add_shorts(short one, short two)
        {
           return one + two;
        }

        void* get_raw_pointer()
        {
           return (void*)add_shorts;
        }

        char get_char(char* s, unsigned short num)
        {
           return s[num];
        }

        const char *char_check(char x, char y)
        {
           if (y == static_str[0])
              return static_str;
           return NULL;
        }

        int get_array_elem(int* stuff, int num)
        {
           return stuff[num];
        }

        struct x* get_array_elem_s(struct x** array, int num)
        {
           return array[num];
        }

        long long some_huge_value()
        {
           return 1LL<<42;
        }

        unsigned long long some_huge_uvalue()
        {
           return 1LL<<42;
        }

        long long pass_ll(long long x)
        {
           return x;
        }

        static int prebuilt_array1[] = {3};

        int* allocate_array()
        {
            return prebuilt_array1;
        }

        long long runcallback(long long(*callback)())
        {
            return callback();
        }

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        long op_x_y(struct x_y s, long(*callback)(struct x_y))
        {
            return callback(s);
        }

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }

        struct s2a {
            int bah[2];
        };

        struct s2a get_s2a(void) {
            struct s2a outp;
            outp.bah[0] = 4;
            outp.bah[1] = 5;
            return outp;
        }

        int check_s2a(struct s2a inp) {
            return (inp.bah[0] == 4 && inp.bah[1] == 5);
        }

        int AAA_first_ordinal_function()
        {
            return 42;
        }

        typedef union {
            short x;
            long y;
        } UN;

        UN ret_un_func(UN inp)
        {
            inp.y = inp.x * 100;
            return inp;
        }
        
        '''))
        symbols = """get_char char_check get_raw_pointer
                     add_shorts
                     inner_struct_elem create_double_struct free_double_struct
                     get_array_elem get_array_elem_s
                     nothing
                     some_huge_value some_huge_uvalue pass_ll
                     runcallback
                     allocate_array
                     static_int static_double static_longdouble
                     sum_x_y op_x_y
                     give perturb get_s2a check_s2a
                     AAA_first_ordinal_function
                     ret_un_func
                  """.split()
        eci = ExternalCompilationInfo(export_symbols=symbols)
        return str(platform.compile([c_file], eci, 'x', standalone=False))
Пример #29
0
    def test_ret_struct_val(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source(
                """
        #include <stdlib.h>
        #include <stdio.h>

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }
        
        """
            )
        )
        eci = ExternalCompilationInfo(export_symbols=["give", "perturb"])
        lib_name = str(platform.compile([c_file], eci, "x", standalone=False))

        lib = CDLL(lib_name)

        size = ffi_type_sshort.c_size * 2
        alignment = ffi_type_sshort.c_alignment
        tpe = make_struct_ffitype_e(size, alignment, [ffi_type_sshort] * 2)

        give = lib.getrawpointer("give", [ffi_type_sshort, ffi_type_sshort], tpe.ffistruct)
        inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor="raw")
        inbuffer[0] = rffi.cast(rffi.SHORT, 40)
        inbuffer[1] = rffi.cast(rffi.SHORT, 72)

        outbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor="raw")

        give.call(
            [rffi.cast(rffi.VOIDP, inbuffer), rffi.cast(rffi.VOIDP, rffi.ptradd(inbuffer, 1))],
            rffi.cast(rffi.VOIDP, outbuffer),
        )

        assert outbuffer[0] == 40
        assert outbuffer[1] == 72

        perturb = lib.getrawpointer("perturb", [tpe.ffistruct], tpe.ffistruct)

        inbuffer[0] = rffi.cast(rffi.SHORT, 7)
        inbuffer[1] = rffi.cast(rffi.SHORT, 11)

        perturb.call([rffi.cast(rffi.VOIDP, inbuffer)], rffi.cast(rffi.VOIDP, outbuffer))

        assert inbuffer[0] == 7
        assert inbuffer[1] == 11

        assert outbuffer[0] == 14
        assert outbuffer[1] == 33

        lltype.free(outbuffer, flavor="raw")
        lltype.free(inbuffer, flavor="raw")
        del give
        del perturb
        lltype.free(tpe, flavor="raw")
        del lib

        assert not ALLOCATED