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, )
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,)
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)
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))
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
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)
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
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))
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))
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
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
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
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
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)
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
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
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)
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)
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
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
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))
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
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))
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
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))
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