ffi 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- data/README.rdoc +19 -0
- data/Rakefile +65 -55
- data/ext/{AbstractMemory.c → ffi_c/AbstractMemory.c} +67 -40
- data/ext/{AbstractMemory.h → ffi_c/AbstractMemory.h} +10 -8
- data/ext/{AutoPointer.c → ffi_c/AutoPointer.c} +17 -8
- data/ext/{AutoPointer.h → ffi_c/AutoPointer.h} +0 -0
- data/ext/ffi_c/Buffer.c +136 -0
- data/ext/{Callback.c → ffi_c/Callback.c} +60 -35
- data/ext/{Callback.h → ffi_c/Callback.h} +1 -7
- data/ext/{Invoker.c → ffi_c/Invoker.c} +472 -102
- data/ext/ffi_c/MemoryPointer.c +146 -0
- data/ext/{MemoryPointer.h → ffi_c/MemoryPointer.h} +2 -7
- data/ext/ffi_c/NativeLibrary.c +149 -0
- data/ext/{NativeLibrary.h → ffi_c/NativeLibrary.h} +0 -0
- data/ext/ffi_c/NullPointer.c +104 -0
- data/ext/{Platform.c → ffi_c/Platform.c} +0 -0
- data/ext/{Platform.h → ffi_c/Platform.h} +0 -7
- data/ext/{Pointer.c → ffi_c/Pointer.c} +35 -15
- data/ext/{Pointer.h → ffi_c/Pointer.h} +4 -2
- data/ext/ffi_c/Struct.c +542 -0
- data/ext/ffi_c/Struct.h +26 -0
- data/ext/ffi_c/Types.c +76 -0
- data/ext/{Types.h → ffi_c/Types.h} +23 -28
- data/ext/{compat.h → ffi_c/compat.h} +2 -2
- data/ext/{extconf.rb → ffi_c/extconf.rb} +12 -7
- data/ext/ffi_c/ffi.c +99 -0
- data/ext/ffi_c/ffi.mk +23 -0
- data/ext/{libffi.darwin.mk → ffi_c/libffi.darwin.mk} +0 -0
- data/ext/ffi_c/libffi.mk +11 -0
- data/ext/{libffi → ffi_c/libffi}/ChangeLog +0 -0
- data/ext/{libffi → ffi_c/libffi}/ChangeLog.libffi +0 -0
- data/ext/{libffi → ffi_c/libffi}/ChangeLog.libgcj +0 -0
- data/ext/{libffi → ffi_c/libffi}/ChangeLog.v1 +0 -0
- data/ext/{libffi → ffi_c/libffi}/LICENSE +0 -0
- data/ext/{libffi → ffi_c/libffi}/Makefile.am +0 -0
- data/ext/{libffi → ffi_c/libffi}/Makefile.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/README +0 -0
- data/ext/{libffi → ffi_c/libffi}/TODO +0 -0
- data/ext/{libffi → ffi_c/libffi}/acinclude.m4 +0 -0
- data/ext/{libffi → ffi_c/libffi}/aclocal.m4 +0 -0
- data/ext/{libffi → ffi_c/libffi}/compile +0 -0
- data/ext/{libffi → ffi_c/libffi}/config.guess +0 -0
- data/ext/{libffi → ffi_c/libffi}/config.sub +0 -0
- data/ext/{libffi → ffi_c/libffi}/configure +0 -0
- data/ext/{libffi → ffi_c/libffi}/configure.ac +0 -0
- data/ext/{libffi → ffi_c/libffi}/configure.host +0 -0
- data/ext/{libffi → ffi_c/libffi}/depcomp +0 -0
- data/ext/{libffi → ffi_c/libffi}/doc/libffi.info +0 -0
- data/ext/{libffi → ffi_c/libffi}/doc/libffi.texi +0 -0
- data/ext/{libffi → ffi_c/libffi}/doc/stamp-vti +0 -0
- data/ext/{libffi → ffi_c/libffi}/doc/version.texi +0 -0
- data/ext/{libffi → ffi_c/libffi}/fficonfig.h.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/include/Makefile.am +0 -0
- data/ext/{libffi → ffi_c/libffi}/include/Makefile.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/include/ffi.h.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/include/ffi_common.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/install-sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/libffi.pc.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/libtool-version +0 -0
- data/ext/{libffi → ffi_c/libffi}/ltcf-c.sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/ltcf-cxx.sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/ltcf-gcj.sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/ltconfig +0 -0
- data/ext/{libffi → ffi_c/libffi}/ltmain.sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/man/Makefile.am +0 -0
- data/ext/{libffi → ffi_c/libffi}/man/Makefile.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/man/ffi.3 +0 -0
- data/ext/{libffi → ffi_c/libffi}/man/ffi_call.3 +0 -0
- data/ext/{libffi → ffi_c/libffi}/man/ffi_prep_cif.3 +0 -0
- data/ext/{libffi → ffi_c/libffi}/mdate-sh +0 -0
- data/ext/{libffi → ffi_c/libffi}/missing +0 -0
- data/ext/{libffi → ffi_c/libffi}/mkinstalldirs +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/alpha/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/alpha/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/alpha/osf.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/arm/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/arm/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/arm/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/closures.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/cris/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/cris/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/cris/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/debug.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/dlmalloc.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/frv/eabi.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/frv/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/frv/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/ia64/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/ia64/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/ia64/ia64_flags.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/ia64/unix.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/java_raw_api.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m32r/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m32r/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m32r/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m68k/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m68k/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/m68k/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/mips/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/mips/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/mips/n32.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/mips/o32.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/pa/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/pa/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/pa/hpux32.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/pa/linux.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix_closure.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/asm.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin_closure.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi_darwin.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64_closure.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/ppc_closure.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/powerpc/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/prep_cif.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/raw_api.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/s390/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/s390/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/s390/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh64/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh64/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sh64/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sparc/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sparc/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sparc/v8.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/sparc/v9.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/types.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/darwin.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/darwin64.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/ffi.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/ffi64.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/ffitarget.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/freebsd.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/sysv.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/unix64.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/src/x86/win32.S +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.am +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.in +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/config/default.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/lib/libffi-dg.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/lib/target-libpath.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/lib/wrapper.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/call.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn0.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn3.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn4.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn5.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn6.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_stdcall.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_12byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_16byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_18byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_19byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_1_1byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_24byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_2byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3_1byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4_1byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5_1_byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_64byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6_1_byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7_1_byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_8byte.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_double.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_float.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_longdouble.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_pointer.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint16.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint32.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint64.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint16.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint32.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint64.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_double.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_float.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_schar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshort.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshortchar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_uchar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushort.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushortchar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_schar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sint.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sshort.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uchar.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uint.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ulonglong.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ushort.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/ffitest.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float3.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float4.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many_win32.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/negint.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct10.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct3.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct4.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct5.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct6.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct7.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct8.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct9.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/problem1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/promotion.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/pyobjc-tc.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl3.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ldl.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sc.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sl.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_uc.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ul.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen_win32.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct1.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct2.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct3.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct4.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct5.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct6.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct7.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct8.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct9.c +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/ffitestcxx.h +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/special.exp +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest.cc +0 -0
- data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest_ffi_call.cc +0 -0
- data/ext/{libffi → ffi_c/libffi}/texinfo.tex +0 -0
- data/ext/{rbffi.h → ffi_c/rbffi.h} +1 -8
- data/lib/ffi/autopointer.rb +7 -7
- data/lib/ffi/buffer.rb +0 -25
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/library.rb +103 -37
- data/lib/ffi/memorypointer.rb +25 -28
- data/lib/ffi/platform.rb +2 -2
- data/lib/ffi/pointer.rb +21 -7
- data/lib/ffi/struct.rb +161 -179
- data/lib/ffi/types.rb +3 -3
- data/lib/ffi/union.rb +17 -0
- data/nbproject/configurations.xml +98 -88
- data/samples/hello.rb +1 -2
- data/samples/sample_helper.rb +6 -0
- data/{specs → spec/ffi}/buffer_spec.rb +0 -0
- data/{specs → spec/ffi}/callback_spec.rb +114 -89
- data/{specs → spec/ffi}/errno_spec.rb +0 -0
- data/spec/ffi/library_spec.rb +144 -0
- data/{specs → spec/ffi}/managed_struct_spec.rb +12 -1
- data/{specs → spec/ffi}/number_spec.rb +34 -16
- data/{specs → spec/ffi}/pointer_spec.rb +46 -2
- data/{specs → spec/ffi}/rbx/attach_function_spec.rb +2 -1
- data/{specs → spec/ffi}/rbx/memory_pointer_spec.rb +19 -19
- data/{specs → spec/ffi}/rbx/spec_helper.rb +0 -0
- data/{specs → spec/ffi}/rbx/struct_spec.rb +0 -0
- data/spec/ffi/spec_helper.rb +13 -0
- data/{specs → spec/ffi}/string_spec.rb +8 -0
- data/spec/ffi/struct_spec.rb +453 -0
- data/{specs → spec/ffi}/typedef_spec.rb +3 -3
- data/spec/ffi/union_spec.rb +60 -0
- data/{specs → spec/ffi}/variadic_spec.rb +0 -0
- data/spec/spec.opts +4 -0
- metadata +356 -334
- data/README +0 -0
- data/ext/Buffer.c +0 -98
- data/ext/MemoryPointer.c +0 -99
- data/ext/NativeLibrary.c +0 -90
- data/ext/Types.c +0 -76
- data/ext/ffi.c +0 -64
- data/ext/ffi.mk +0 -24
- data/ext/libffi.mk +0 -10
- data/gen/Rakefile +0 -12
- data/specs/library_spec.rb +0 -55
- data/specs/spec_helper.rb +0 -9
- data/specs/struct_spec.rb +0 -223
data/lib/ffi/buffer.rb
CHANGED
@@ -1,25 +0,0 @@
|
|
1
|
-
module FFI
|
2
|
-
class Buffer
|
3
|
-
def self.__calc_size(type)
|
4
|
-
if type.kind_of? Fixnum
|
5
|
-
type
|
6
|
-
elsif type.kind_of? Symbol
|
7
|
-
FFI.type_size(type)
|
8
|
-
else
|
9
|
-
type.size
|
10
|
-
end
|
11
|
-
end
|
12
|
-
def self.new(size, count=nil, clear=true)
|
13
|
-
self.__alloc_inout(self.__calc_size(size), count, clear)
|
14
|
-
end
|
15
|
-
def self.alloc_in(size, count=nil, clear=true)
|
16
|
-
self.__alloc_in(self.__calc_size(size), count, clear)
|
17
|
-
end
|
18
|
-
def self.alloc_out(size, count=nil, clear=true)
|
19
|
-
self.__alloc_out(self.__calc_size(size), count, clear)
|
20
|
-
end
|
21
|
-
def self.alloc_inout(size, count=nil, clear=true)
|
22
|
-
self.__alloc_inout(self.__calc_size(size), count, clear)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/ffi/ffi.rb
CHANGED
data/lib/ffi/library.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
module FFI::Library
|
2
2
|
DEFAULT = FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY)
|
3
3
|
|
4
|
-
# TODO: Rubinius does *names here and saves the array. Multiple libs?
|
5
4
|
def ffi_lib(*names)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
ffi_libs = []
|
6
|
+
names.each do |name|
|
7
|
+
[ name, FFI.map_library_name(name) ].each do |libname|
|
8
|
+
begin
|
9
|
+
lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
|
10
|
+
if lib
|
11
|
+
ffi_libs << lib
|
12
|
+
break
|
13
|
+
end
|
14
|
+
rescue LoadError => ex
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
|
-
raise LoadError, "Could not open any of [#{
|
17
|
+
end
|
18
|
+
raise LoadError, "Could not open any of [#{names.join(", ")}]" if ffi_libs.empty?
|
17
19
|
@ffi_libs = ffi_libs
|
18
20
|
end
|
19
21
|
def ffi_convention(convention)
|
@@ -35,21 +37,8 @@ module FFI::Library
|
|
35
37
|
convention = defined?(@ffi_convention) ? @ffi_convention : :default
|
36
38
|
|
37
39
|
# Convert :foo to the native type
|
38
|
-
|
39
|
-
arg_types.
|
40
|
-
begin
|
41
|
-
find_type(e)
|
42
|
-
rescue FFI::TypeError => ex
|
43
|
-
if defined?(@ffi_callbacks) && @ffi_callbacks.has_key?(e)
|
44
|
-
callback_count += 1
|
45
|
-
@ffi_callbacks[e]
|
46
|
-
elsif e.is_a?(Class) && e < FFI::Struct
|
47
|
-
FFI::NativeType::POINTER
|
48
|
-
else
|
49
|
-
raise ex
|
50
|
-
end
|
51
|
-
end
|
52
|
-
}
|
40
|
+
arg_types.map! { |e| find_type(e) }
|
41
|
+
has_callback = arg_types.any? {|t| t.kind_of?(FFI::CallbackInfo)}
|
53
42
|
options = Hash.new
|
54
43
|
options[:convention] = convention
|
55
44
|
options[:type_map] = @ffi_typedefs if defined?(@ffi_typedefs)
|
@@ -69,24 +58,97 @@ module FFI::Library
|
|
69
58
|
params = (1..arity).map {|i| "a#{i}" }.join(",")
|
70
59
|
|
71
60
|
# Always use rest args for functions with callback parameters
|
72
|
-
if
|
61
|
+
if has_callback || invoker.kind_of?(FFI::VariadicInvoker)
|
73
62
|
params = "*args, &block"
|
74
63
|
end
|
75
|
-
call = arity <= 3 &&
|
64
|
+
call = arity <= 3 && !has_callback && !invoker.kind_of?(FFI::VariadicInvoker)? "call#{arity}" : "call"
|
76
65
|
|
77
66
|
#
|
78
67
|
# Attach the invoker to this module as 'mname'.
|
79
68
|
#
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
69
|
+
if !has_callback && !invoker.kind_of?(FFI::VariadicInvoker)
|
70
|
+
invoker.attach(self, mname.to_s)
|
71
|
+
else
|
72
|
+
self.module_eval <<-code
|
73
|
+
@@#{mname} = invoker
|
74
|
+
def self.#{mname}(#{params})
|
75
|
+
@@#{mname}.#{call}(#{params})
|
76
|
+
end
|
77
|
+
def #{mname}(#{params})
|
78
|
+
@@#{mname}.#{call}(#{params})
|
79
|
+
end
|
80
|
+
code
|
81
|
+
end
|
82
|
+
invoker
|
83
|
+
end
|
84
|
+
def attach_variable(mname, a1, a2 = nil)
|
85
|
+
cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ]
|
86
|
+
libraries = defined?(@ffi_libs) ? @ffi_libs : [ DEFAULT ]
|
87
|
+
address = nil
|
88
|
+
libraries.each do |lib|
|
89
|
+
begin
|
90
|
+
address = lib.find_symbol(cname.to_s)
|
91
|
+
break unless address.nil?
|
92
|
+
rescue LoadError
|
84
93
|
end
|
85
|
-
|
86
|
-
|
94
|
+
end
|
95
|
+
raise FFI::NotFoundError.new(cname, libraries) if address.nil?
|
96
|
+
case ffi_type = find_type(type)
|
97
|
+
when :pointer, FFI::NativeType::POINTER
|
98
|
+
op = :pointer
|
99
|
+
when :char, FFI::NativeType::INT8
|
100
|
+
op = :int8
|
101
|
+
when :uchar, FFI::NativeType::UINT8
|
102
|
+
op = :uint8
|
103
|
+
when :short, FFI::NativeType::INT16
|
104
|
+
op = :int16
|
105
|
+
when :ushort, FFI::NativeType::UINT16
|
106
|
+
op = :uint16
|
107
|
+
when :int, FFI::NativeType::INT32
|
108
|
+
op = :int32
|
109
|
+
when :uint, FFI::NativeType::UINT32
|
110
|
+
op = :uint32
|
111
|
+
when :long, FFI::NativeType::LONG
|
112
|
+
op = :long
|
113
|
+
when :ulong, FFI::NativeType::ULONG
|
114
|
+
op = :ulong
|
115
|
+
when :long_long, FFI::NativeType::INT64
|
116
|
+
op = :int64
|
117
|
+
when :ulong_long, FFI::NativeType::UINT64
|
118
|
+
op = :uint64
|
119
|
+
else
|
120
|
+
if ffi_type.is_a?(FFI::CallbackInfo)
|
121
|
+
op = :callback
|
122
|
+
else
|
123
|
+
raise FFI::TypeError, "Cannot access library variable of type #{type}"
|
87
124
|
end
|
88
|
-
|
89
|
-
|
125
|
+
end
|
126
|
+
#
|
127
|
+
# Attach to this module as mname/mname=
|
128
|
+
#
|
129
|
+
if op == :callback
|
130
|
+
self.module_eval <<-code
|
131
|
+
@@ffi_gvar_#{mname} = address
|
132
|
+
@@ffi_gvar_#{mname}_cbinfo = ffi_type
|
133
|
+
def self.#{mname}
|
134
|
+
raise ArgError, "Cannot get callback fields"
|
135
|
+
end
|
136
|
+
def self.#{mname}=(value)
|
137
|
+
@@ffi_gvar_#{mname}.put_callback(0, value, @@ffi_gvar_#{mname}_cbinfo)
|
138
|
+
end
|
139
|
+
code
|
140
|
+
else
|
141
|
+
self.module_eval <<-code
|
142
|
+
@@ffi_gvar_#{mname} = address
|
143
|
+
def self.#{mname}
|
144
|
+
@@ffi_gvar_#{mname}.get_#{op.to_s}(0)
|
145
|
+
end
|
146
|
+
def self.#{mname}=(value)
|
147
|
+
@@ffi_gvar_#{mname}.put_#{op.to_s}(0, value)
|
148
|
+
end
|
149
|
+
code
|
150
|
+
end
|
151
|
+
address
|
90
152
|
end
|
91
153
|
def callback(name, args, ret)
|
92
154
|
@ffi_callbacks = Hash.new unless defined?(@ffi_callbacks)
|
@@ -103,8 +165,12 @@ module FFI::Library
|
|
103
165
|
@ffi_typedefs[add] = code
|
104
166
|
end
|
105
167
|
def find_type(name)
|
106
|
-
code = if defined?(@ffi_typedefs)
|
168
|
+
code = if defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(name)
|
107
169
|
@ffi_typedefs[name]
|
170
|
+
elsif defined?(@ffi_callbacks) && @ffi_callbacks.has_key?(name)
|
171
|
+
@ffi_callbacks[name]
|
172
|
+
elsif name.is_a?(Class) && name < FFI::Struct
|
173
|
+
FFI::NativeType::POINTER
|
108
174
|
end
|
109
175
|
code = name if !code && name.kind_of?(FFI::CallbackInfo)
|
110
176
|
if code.nil? || code.kind_of?(Symbol)
|
data/lib/ffi/memorypointer.rb
CHANGED
@@ -23,34 +23,34 @@ module FFI
|
|
23
23
|
# with a block yields the MemoryPointer instance and frees the memory
|
24
24
|
# when the block returns. The value returned is the value of the block.
|
25
25
|
|
26
|
-
def self.new(type, count=nil, clear=true)
|
27
|
-
size = if type.kind_of? Fixnum
|
28
|
-
type
|
29
|
-
elsif type.kind_of? Symbol
|
30
|
-
FFI.type_size(type)
|
31
|
-
else
|
32
|
-
type.size
|
33
|
-
end
|
34
|
-
ptr = self.__allocate(size, count, clear)
|
35
|
-
ptr.type_size = size
|
36
|
-
if block_given?
|
37
|
-
begin
|
38
|
-
value = yield ptr
|
39
|
-
ensure
|
40
|
-
ptr.free
|
41
|
-
end
|
42
|
-
value
|
43
|
-
else
|
44
|
-
ptr
|
45
|
-
end
|
46
|
-
end
|
26
|
+
# def self.new(type, count=nil, clear=true)
|
27
|
+
# size = if type.kind_of? Fixnum
|
28
|
+
# type
|
29
|
+
# elsif type.kind_of? Symbol
|
30
|
+
# FFI.type_size(type)
|
31
|
+
# else
|
32
|
+
# type.size
|
33
|
+
# end
|
34
|
+
# ptr = self.__allocate(size, count, clear)
|
35
|
+
# ptr.type_size = size
|
36
|
+
# if block_given?
|
37
|
+
# begin
|
38
|
+
# value = yield ptr
|
39
|
+
# ensure
|
40
|
+
# ptr.free
|
41
|
+
# end
|
42
|
+
# value
|
43
|
+
# else
|
44
|
+
# ptr
|
45
|
+
# end
|
46
|
+
# end
|
47
47
|
def self.from_string(s)
|
48
48
|
ptr = self.new(s.length + 1, 1, false)
|
49
49
|
ptr.put_string(0, s)
|
50
50
|
ptr
|
51
51
|
end
|
52
52
|
# Indicates how many bytes the type that the pointer is cast as uses.
|
53
|
-
attr_accessor :type_size
|
53
|
+
# attr_accessor :type_size
|
54
54
|
|
55
55
|
# Access the MemoryPointer like a C array, accessing the +which+ number
|
56
56
|
# element in memory. The position of the element is calculate from
|
@@ -66,11 +66,8 @@ module FFI
|
|
66
66
|
# int *new_ptr;
|
67
67
|
# new_ptr = &ptr[9];
|
68
68
|
#
|
69
|
-
def [](which)
|
70
|
-
|
71
|
-
|
72
|
-
end
|
69
|
+
# def [](which)
|
70
|
+
# self + (which * type_size)
|
71
|
+
# end
|
73
72
|
end
|
74
73
|
end
|
75
|
-
|
76
|
-
MemoryPointer = FFI::MemoryPointer
|
data/lib/ffi/platform.rb
CHANGED
@@ -14,10 +14,10 @@ module FFI
|
|
14
14
|
"openbsd"
|
15
15
|
when /sunos|solaris/
|
16
16
|
"solaris"
|
17
|
-
when /win/
|
17
|
+
when /win|mingw/
|
18
18
|
"windows"
|
19
19
|
else
|
20
|
-
raise FFI::PlatformError, "Unknown operating system: #{
|
20
|
+
raise FFI::PlatformError, "Unknown operating system: #{Config::CONFIG['host_os']}"
|
21
21
|
end
|
22
22
|
ARCH = case CPU.downcase
|
23
23
|
when /amd64|x86_64/
|
data/lib/ffi/pointer.rb
CHANGED
@@ -35,9 +35,14 @@ module FFI
|
|
35
35
|
def read_long_long
|
36
36
|
get_int64(0)
|
37
37
|
end
|
38
|
+
|
38
39
|
def read_pointer
|
39
40
|
get_pointer(0)
|
40
41
|
end
|
42
|
+
def write_pointer(ptr)
|
43
|
+
put_pointer(0, ptr)
|
44
|
+
end
|
45
|
+
|
41
46
|
def read_float
|
42
47
|
get_float32(0)
|
43
48
|
end
|
@@ -59,20 +64,20 @@ module FFI
|
|
59
64
|
get_string(0)
|
60
65
|
end
|
61
66
|
def write_string_length(str, len)
|
62
|
-
|
67
|
+
put_bytes(0, str, 0, len)
|
63
68
|
end
|
64
69
|
def write_string(str, len=nil)
|
65
70
|
len = str.size unless len
|
66
71
|
# Write the string data without NUL termination
|
67
|
-
|
72
|
+
put_bytes(0, str, 0, len)
|
68
73
|
end
|
69
74
|
def read_array_of_type(type, reader, length)
|
70
75
|
ary = []
|
71
76
|
size = FFI.type_size(type)
|
72
77
|
tmp = self
|
73
|
-
length.times {
|
78
|
+
length.times { |j|
|
74
79
|
ary << tmp.send(reader)
|
75
|
-
tmp += size
|
80
|
+
tmp += size unless j == length-1 # avoid OOB
|
76
81
|
}
|
77
82
|
ary
|
78
83
|
end
|
@@ -80,9 +85,9 @@ module FFI
|
|
80
85
|
def write_array_of_type(type, writer, ary)
|
81
86
|
size = FFI.type_size(type)
|
82
87
|
tmp = self
|
83
|
-
ary.
|
88
|
+
ary.each_with_index {|i, j|
|
84
89
|
tmp.send(writer, i)
|
85
|
-
tmp += size
|
90
|
+
tmp += size unless j == ary.length-1 # avoid OOB
|
86
91
|
}
|
87
92
|
self
|
88
93
|
end
|
@@ -101,5 +106,14 @@ module FFI
|
|
101
106
|
def write_array_of_long(ary)
|
102
107
|
put_array_of_long(0, ary)
|
103
108
|
end
|
109
|
+
|
110
|
+
def read_array_of_pointer(length)
|
111
|
+
read_array_of_type(:pointer, :read_pointer, length)
|
112
|
+
end
|
113
|
+
|
114
|
+
def write_array_of_pointer(ary)
|
115
|
+
write_array_of_type(:pointer, :write_pointer, ary)
|
116
|
+
end
|
117
|
+
|
104
118
|
end
|
105
|
-
end
|
119
|
+
end
|
data/lib/ffi/struct.rb
CHANGED
@@ -1,164 +1,103 @@
|
|
1
1
|
require 'ffi/platform'
|
2
2
|
module FFI
|
3
3
|
class StructLayout
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
attr_reader :size, :align
|
5
|
+
|
6
|
+
def members
|
7
|
+
@field_names
|
7
8
|
end
|
8
|
-
|
9
|
-
|
10
|
-
@fields[name]
|
9
|
+
def offsets
|
10
|
+
@fields.map { |name, field| [name, field.offset] }.sort { |a, b| a[1] <=> b[1] }
|
11
11
|
end
|
12
|
-
def
|
13
|
-
@
|
12
|
+
def offset_of(field_name)
|
13
|
+
@fields[field_name].offset
|
14
14
|
end
|
15
15
|
end
|
16
16
|
class StructLayoutBuilder
|
17
17
|
class Field
|
18
|
-
def initialize(off)
|
19
|
-
@off = off
|
20
|
-
end
|
21
|
-
|
22
|
-
def offset
|
23
|
-
@off
|
24
|
-
end
|
25
18
|
def size
|
26
|
-
self.size
|
19
|
+
self.class.size
|
27
20
|
end
|
28
21
|
def align
|
29
|
-
self.align
|
30
|
-
end
|
31
|
-
def self.align
|
32
|
-
self.size
|
33
|
-
end
|
34
|
-
end
|
35
|
-
class Signed8 < Field
|
36
|
-
def self.size; 8; end
|
37
|
-
def self.align; Platform::INT8_ALIGN; end
|
38
|
-
def put(ptr, val)
|
39
|
-
ptr.put_int8(@off, val)
|
40
|
-
end
|
41
|
-
def get(ptr)
|
42
|
-
ptr.get_int8(@off)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
class Unsigned8 < Field
|
46
|
-
def self.size; 8; end
|
47
|
-
def self.align; Platform::INT8_ALIGN; end
|
48
|
-
def put(ptr, val)
|
49
|
-
ptr.put_uint8(@off, val)
|
50
|
-
end
|
51
|
-
def get(ptr)
|
52
|
-
ptr.get_uint8(@off)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
class Signed16 < Field
|
56
|
-
def self.size; 16; end
|
57
|
-
def self.align; Platform::INT16_ALIGN; end
|
58
|
-
def put(ptr, val)
|
59
|
-
ptr.put_int16(@off, val)
|
60
|
-
end
|
61
|
-
def get(ptr)
|
62
|
-
ptr.get_int16(@off)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
class Unsigned16 < Field
|
66
|
-
def self.size; 16; end
|
67
|
-
def self.align; Platform::INT16_ALIGN; end
|
68
|
-
def put(ptr, val)
|
69
|
-
ptr.put_uint16(@off, val)
|
70
|
-
end
|
71
|
-
def get(ptr)
|
72
|
-
ptr.get_uint16(@off)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
class Signed32 < Field
|
76
|
-
def self.size; 32; end
|
77
|
-
def self.align; Platform::INT32_ALIGN; end
|
78
|
-
def put(ptr, val)
|
79
|
-
ptr.put_int32(@off, val)
|
80
|
-
end
|
81
|
-
def get(ptr)
|
82
|
-
ptr.get_int32(@off)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
class Unsigned32 < Field
|
86
|
-
def self.size; 32; end
|
87
|
-
def self.align; Platform::INT32_ALIGN; end
|
88
|
-
def put(ptr, val)
|
89
|
-
ptr.put_uint32(@off, val)
|
90
|
-
end
|
91
|
-
def get(ptr)
|
92
|
-
ptr.get_uint32(@off)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
class Signed64 < Field
|
96
|
-
def self.size; 64; end
|
97
|
-
def self.align; Platform::INT64_ALIGN; end
|
98
|
-
def put(ptr, val)
|
99
|
-
ptr.put_int64(@off, val)
|
100
|
-
end
|
101
|
-
def get(ptr)
|
102
|
-
ptr.get_int64(@off)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
class Unsigned64 < Field
|
106
|
-
def self.size; 64; end
|
107
|
-
def self.align; Platform::INT64_ALIGN; end
|
108
|
-
def put(ptr, val)
|
109
|
-
ptr.put_uint64(@off, val)
|
110
|
-
end
|
111
|
-
def get(ptr)
|
112
|
-
ptr.get_uint64(@off)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
class FloatField < Field
|
116
|
-
def self.size; Platform::FLOAT_SIZE; end
|
117
|
-
def self.align; Platform::FLOAT_ALIGN; end
|
118
|
-
def put(ptr, val)
|
119
|
-
ptr.put_float32(@off, val)
|
22
|
+
self.class.align
|
120
23
|
end
|
121
|
-
def
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
125
|
-
class DoubleField < Field
|
126
|
-
def self.size; Platform::DOUBLE_SIZE; end
|
127
|
-
def self.align; Platform::DOUBLE_ALIGN; end
|
128
|
-
def put(ptr, val)
|
129
|
-
ptr.put_float64(@off, val)
|
24
|
+
def offset
|
25
|
+
@off
|
130
26
|
end
|
131
|
-
def
|
132
|
-
|
27
|
+
def self.size
|
28
|
+
const_get(:SIZE)
|
133
29
|
end
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
30
|
+
def self.align
|
31
|
+
const_get(:ALIGN)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def self.struct_field_class_from(type)
|
35
|
+
klass_name = type.name.split('::').last
|
36
|
+
code = <<-code
|
37
|
+
class StructField_#{klass_name} < Field
|
38
|
+
@info = #{type}
|
39
|
+
class << self
|
40
|
+
attr_reader :info
|
41
|
+
def size
|
42
|
+
#{type.size} * 8
|
43
|
+
end
|
44
|
+
def align
|
45
|
+
#{type.align}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
def get(ptr)
|
49
|
+
self.class.info.new(ptr + @off)
|
50
|
+
end
|
140
51
|
end
|
141
|
-
|
142
|
-
|
52
|
+
StructField_#{klass_name}
|
53
|
+
code
|
54
|
+
self.module_eval(code)
|
55
|
+
end
|
56
|
+
def self.array_field_class_from(type, num)
|
57
|
+
klass_name = type.name.split('::').last
|
58
|
+
code = <<-code
|
59
|
+
class ArrayField_#{klass_name}_#{num} < Field
|
60
|
+
@info = #{type}
|
61
|
+
@num = #{num}
|
62
|
+
class << self
|
63
|
+
attr_reader :info, :num
|
64
|
+
def size
|
65
|
+
#{type.size} * #{num}
|
66
|
+
end
|
67
|
+
def align
|
68
|
+
#{type.align}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
def get(ptr)
|
72
|
+
@array ? @array : get_array_data(ptr)
|
73
|
+
end
|
74
|
+
private
|
75
|
+
def get_array_data(ptr)
|
76
|
+
@array = FFI::Struct::Array.new(ptr + @off, self.class.info, self.class.num)
|
77
|
+
end
|
143
78
|
end
|
79
|
+
ArrayField_#{klass_name}_#{num}
|
80
|
+
code
|
81
|
+
self.module_eval(code)
|
144
82
|
end
|
145
|
-
class
|
83
|
+
class CallbackField < Field
|
146
84
|
def self.size; Platform::ADDRESS_SIZE; end
|
147
85
|
def self.align; Platform::ADDRESS_ALIGN; end
|
148
|
-
def put(ptr,
|
149
|
-
|
86
|
+
def put(ptr, proc)
|
87
|
+
ptr.put_callback(@off, proc, @info)
|
150
88
|
end
|
151
89
|
def get(ptr)
|
152
|
-
|
153
|
-
(strp.nil? || strp.null?) ? nil : strp.get_string(0)
|
90
|
+
raise ArgumentError, "Cannot get callback fields"
|
154
91
|
end
|
155
92
|
end
|
156
93
|
def initialize
|
94
|
+
@field_names = []
|
157
95
|
@fields = {}
|
158
96
|
@size = 0
|
97
|
+
@min_align = 1
|
159
98
|
end
|
160
|
-
def
|
161
|
-
|
99
|
+
def native_field_class_from(type)
|
100
|
+
case type
|
162
101
|
when :char, NativeType::INT8
|
163
102
|
Signed8
|
164
103
|
when :uchar, NativeType::UINT8
|
@@ -187,17 +126,35 @@ module FFI
|
|
187
126
|
PointerField
|
188
127
|
when :string, NativeType::STRING
|
189
128
|
StringField
|
190
|
-
else
|
191
|
-
raise ArgumentError, "Unknown type: #{type}"
|
192
129
|
end
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
130
|
+
end
|
131
|
+
def callback_field_class_from(type)
|
132
|
+
return CallbackField, type if type.is_a?(FFI::CallbackInfo)
|
133
|
+
end
|
134
|
+
def struct_field_class_from(type)
|
135
|
+
self.class.struct_field_class_from(type) if type.is_a?(Class) and type < FFI::Struct
|
136
|
+
end
|
137
|
+
def array_field_class_from(type)
|
138
|
+
self.class.array_field_class_from(field_class_from(type[0]), type[1]) if type.is_a?(Array)
|
139
|
+
end
|
140
|
+
def field_class_from(type)
|
141
|
+
field_class = native_field_class_from(type) ||
|
142
|
+
callback_field_class_from(type) ||
|
143
|
+
array_field_class_from(type) ||
|
144
|
+
struct_field_class_from(type)
|
145
|
+
field_class or raise ArgumentError, "Unknown type: #{type}"
|
146
|
+
end
|
147
|
+
def add_field(name, type, offset = nil)
|
148
|
+
field_class, info = field_class_from(type)
|
149
|
+
off = calc_alignment_of(field_class, offset)
|
150
|
+
calc_current_size(off, field_class.size / 8)
|
151
|
+
@field_names << name
|
152
|
+
@fields[name] = field_class.new(off, info)
|
153
|
+
@min_align = field_class.align if field_class.align > @min_align
|
198
154
|
end
|
199
155
|
def build
|
200
|
-
|
156
|
+
align = @min_align / 8
|
157
|
+
StructLayout.new @field_names, @fields, align + ((@size - 1) & ~(align - 1)), @min_align
|
201
158
|
end
|
202
159
|
def align(offset, bits)
|
203
160
|
bytes = bits / 8
|
@@ -205,28 +162,38 @@ module FFI
|
|
205
162
|
off = offset;
|
206
163
|
((off & mask) != 0) ? (off & ~mask) + bytes : off
|
207
164
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
attr_reader :pointer
|
212
|
-
|
213
|
-
def initialize(pointer = nil, *spec)
|
214
|
-
@cspec = self.class.layout(*spec)
|
215
|
-
|
216
|
-
if pointer then
|
217
|
-
@pointer = pointer
|
218
|
-
else
|
219
|
-
@pointer = MemoryPointer.new size
|
220
|
-
end
|
221
|
-
end
|
222
|
-
def self.alloc_inout(clear = true)
|
223
|
-
self.new(Buffer.alloc_inout(@size, 1, clear))
|
165
|
+
private
|
166
|
+
def calc_alignment_of(field_class, offset)
|
167
|
+
offset ? offset.to_i : align(@size, field_class.align)
|
224
168
|
end
|
225
|
-
def
|
226
|
-
|
169
|
+
def calc_current_size(offset, size)
|
170
|
+
@size = offset + size
|
227
171
|
end
|
228
|
-
|
229
|
-
|
172
|
+
end
|
173
|
+
class Struct
|
174
|
+
class Array
|
175
|
+
include Enumerable
|
176
|
+
def initialize(ptr, type, num)
|
177
|
+
@pointer, @type, @num = ptr, type, num
|
178
|
+
end
|
179
|
+
def to_ptr
|
180
|
+
@pointer
|
181
|
+
end
|
182
|
+
def to_a
|
183
|
+
get_array_data(@pointer)
|
184
|
+
end
|
185
|
+
def size
|
186
|
+
@num * @type.size / 8
|
187
|
+
end
|
188
|
+
def each(&blk)
|
189
|
+
to_a.each(&blk)
|
190
|
+
end
|
191
|
+
private
|
192
|
+
def get_array_data(ptr)
|
193
|
+
(0..@num - 1).inject([]) do |array, index|
|
194
|
+
array << @type.new(0).get(ptr + index * @type.size / 8)
|
195
|
+
end
|
196
|
+
end
|
230
197
|
end
|
231
198
|
def self.size
|
232
199
|
@size
|
@@ -234,27 +201,39 @@ module FFI
|
|
234
201
|
def self.members
|
235
202
|
@layout.members
|
236
203
|
end
|
204
|
+
def self.align
|
205
|
+
@layout.align
|
206
|
+
end
|
207
|
+
def self.offsets
|
208
|
+
@layout.offsets
|
209
|
+
end
|
210
|
+
def self.offset_of(field_name)
|
211
|
+
@layout.offset_of(field_name)
|
212
|
+
end
|
237
213
|
def size
|
238
214
|
self.class.size
|
239
215
|
end
|
240
|
-
def
|
241
|
-
|
242
|
-
end
|
243
|
-
def []=(field, val)
|
244
|
-
@cspec[field].put(@pointer, val)
|
216
|
+
def align
|
217
|
+
self.class.align
|
245
218
|
end
|
246
219
|
def members
|
247
|
-
|
220
|
+
layout.members
|
248
221
|
end
|
249
222
|
def values
|
250
|
-
|
223
|
+
layout.members.map { |m| self[m] }
|
224
|
+
end
|
225
|
+
def offsets
|
226
|
+
self.class.offsets
|
227
|
+
end
|
228
|
+
def offset_of(field_name)
|
229
|
+
self.class.offset_of(field_name)
|
251
230
|
end
|
252
231
|
def clear
|
253
|
-
|
232
|
+
pointer.clear
|
254
233
|
self
|
255
234
|
end
|
256
235
|
def to_ptr
|
257
|
-
|
236
|
+
pointer
|
258
237
|
end
|
259
238
|
def self.in
|
260
239
|
:buffer_in
|
@@ -262,9 +241,10 @@ module FFI
|
|
262
241
|
def self.out
|
263
242
|
:buffer_out
|
264
243
|
end
|
265
|
-
end
|
266
|
-
class Struct < BaseStruct
|
267
244
|
private
|
245
|
+
def self.builder
|
246
|
+
StructLayoutBuilder.new
|
247
|
+
end
|
268
248
|
def self.enclosing_module
|
269
249
|
begin
|
270
250
|
mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
|
@@ -273,12 +253,16 @@ module FFI
|
|
273
253
|
nil
|
274
254
|
end
|
275
255
|
end
|
256
|
+
def self.is_a_struct?(type)
|
257
|
+
type.is_a?(Class) and type < Struct
|
258
|
+
end
|
276
259
|
def self.find_type(type, mod = nil)
|
277
|
-
return
|
260
|
+
return type if is_a_struct?(type) or type.is_a?(::Array)
|
261
|
+
mod ? mod.find_type(type) : FFI.find_type(type)
|
278
262
|
end
|
279
263
|
def self.hash_layout(spec)
|
280
264
|
raise "Ruby version not supported" if RUBY_VERSION =~ /1.8.*/
|
281
|
-
builder =
|
265
|
+
builder = self.builder
|
282
266
|
mod = enclosing_module
|
283
267
|
spec[0].each do |name,type|
|
284
268
|
builder.add_field(name, find_type(type, mod))
|
@@ -286,14 +270,14 @@ module FFI
|
|
286
270
|
builder.build
|
287
271
|
end
|
288
272
|
def self.array_layout(spec)
|
289
|
-
builder =
|
273
|
+
builder = self.builder
|
290
274
|
mod = enclosing_module
|
291
275
|
i = 0
|
292
276
|
while i < spec.size
|
293
277
|
name, type = spec[i, 2]
|
294
278
|
i += 2
|
295
|
-
code = find_type(type, mod)
|
296
|
-
# If the next param is a
|
279
|
+
code = find_type(type, mod)
|
280
|
+
# If the next param is a Fixnum, it specifies the offset
|
297
281
|
if spec[i].kind_of?(Fixnum)
|
298
282
|
offset = spec[i]
|
299
283
|
i += 1
|
@@ -306,10 +290,8 @@ module FFI
|
|
306
290
|
end
|
307
291
|
public
|
308
292
|
def self.layout(*spec)
|
309
|
-
|
310
293
|
return @layout if spec.size == 0
|
311
294
|
cspec = spec[0].kind_of?(Hash) ? hash_layout(spec) : array_layout(spec)
|
312
|
-
|
313
295
|
@layout = cspec unless self == FFI::Struct
|
314
296
|
@size = cspec.size
|
315
297
|
return cspec
|