ffi 0.5.0-x86-mingw32
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/LICENSE +51 -0
- data/README.rdoc +69 -0
- data/Rakefile +191 -0
- data/ext/ffi_c/AbstractMemory.c +489 -0
- data/ext/ffi_c/AbstractMemory.h +160 -0
- data/ext/ffi_c/ArrayType.c +129 -0
- data/ext/ffi_c/ArrayType.h +58 -0
- data/ext/ffi_c/AutoPointer.c +61 -0
- data/ext/ffi_c/AutoPointer.h +18 -0
- data/ext/ffi_c/Buffer.c +187 -0
- data/ext/ffi_c/Call.c +853 -0
- data/ext/ffi_c/Call.h +86 -0
- data/ext/ffi_c/ClosurePool.c +302 -0
- data/ext/ffi_c/ClosurePool.h +29 -0
- data/ext/ffi_c/DynamicLibrary.c +216 -0
- data/ext/ffi_c/DynamicLibrary.h +22 -0
- data/ext/ffi_c/Function.c +478 -0
- data/ext/ffi_c/Function.h +80 -0
- data/ext/ffi_c/FunctionInfo.c +221 -0
- data/ext/ffi_c/LastError.c +159 -0
- data/ext/ffi_c/LastError.h +18 -0
- data/ext/ffi_c/MemoryPointer.c +178 -0
- data/ext/ffi_c/MemoryPointer.h +20 -0
- data/ext/ffi_c/MethodHandle.c +346 -0
- data/ext/ffi_c/MethodHandle.h +53 -0
- data/ext/ffi_c/Platform.c +59 -0
- data/ext/ffi_c/Platform.h +16 -0
- data/ext/ffi_c/Pointer.c +224 -0
- data/ext/ffi_c/Pointer.h +49 -0
- data/ext/ffi_c/Struct.c +770 -0
- data/ext/ffi_c/Struct.h +80 -0
- data/ext/ffi_c/StructByValue.c +140 -0
- data/ext/ffi_c/StructByValue.h +53 -0
- data/ext/ffi_c/StructLayout.c +450 -0
- data/ext/ffi_c/Type.c +329 -0
- data/ext/ffi_c/Type.h +57 -0
- data/ext/ffi_c/Types.c +103 -0
- data/ext/ffi_c/Types.h +85 -0
- data/ext/ffi_c/Variadic.c +260 -0
- data/ext/ffi_c/compat.h +72 -0
- data/ext/ffi_c/endian.h +40 -0
- data/ext/ffi_c/extconf.rb +30 -0
- data/ext/ffi_c/ffi.c +82 -0
- data/ext/ffi_c/libffi.bsd.mk +34 -0
- data/ext/ffi_c/libffi.darwin.mk +75 -0
- data/ext/ffi_c/libffi.gnu.mk +29 -0
- data/ext/ffi_c/libffi.mk +13 -0
- data/ext/ffi_c/libffi/ChangeLog +3243 -0
- data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
- data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
- data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
- data/ext/ffi_c/libffi/LICENSE +21 -0
- data/ext/ffi_c/libffi/Makefile.am +177 -0
- data/ext/ffi_c/libffi/Makefile.in +1640 -0
- data/ext/ffi_c/libffi/README +328 -0
- data/ext/ffi_c/libffi/TODO +1 -0
- data/ext/ffi_c/libffi/acinclude.m4 +92 -0
- data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
- data/ext/ffi_c/libffi/compile +142 -0
- data/ext/ffi_c/libffi/config.guess +1516 -0
- data/ext/ffi_c/libffi/config.sub +1626 -0
- data/ext/ffi_c/libffi/configure +24414 -0
- data/ext/ffi_c/libffi/configure.ac +365 -0
- data/ext/ffi_c/libffi/configure.host +11 -0
- data/ext/ffi_c/libffi/depcomp +584 -0
- data/ext/ffi_c/libffi/doc/libffi.info +533 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
- data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
- data/ext/ffi_c/libffi/doc/version.texi +4 -0
- data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
- data/ext/ffi_c/libffi/include/Makefile.am +9 -0
- data/ext/ffi_c/libffi/include/Makefile.in +422 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
- data/ext/ffi_c/libffi/install-sh +323 -0
- data/ext/ffi_c/libffi/libffi.pc.in +10 -0
- data/ext/ffi_c/libffi/libtool-version +29 -0
- data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
- data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
- data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
- data/ext/ffi_c/libffi/ltconfig +2862 -0
- data/ext/ffi_c/libffi/ltmain.sh +6930 -0
- data/ext/ffi_c/libffi/man/Makefile.am +8 -0
- data/ext/ffi_c/libffi/man/Makefile.in +395 -0
- data/ext/ffi_c/libffi/man/ffi.3 +31 -0
- data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
- data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
- data/ext/ffi_c/libffi/mdate-sh +201 -0
- data/ext/ffi_c/libffi/missing +353 -0
- data/ext/ffi_c/libffi/mkinstalldirs +158 -0
- data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
- data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
- data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
- data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
- data/ext/ffi_c/libffi/src/closures.c +596 -0
- data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
- data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
- data/ext/ffi_c/libffi/src/debug.c +59 -0
- data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
- data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
- data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
- data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
- data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
- data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
- data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
- data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
- data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
- data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
- data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
- data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
- data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
- data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
- data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
- data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
- data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
- data/ext/ffi_c/libffi/src/raw_api.c +254 -0
- data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
- data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
- data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
- data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
- data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
- data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
- data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
- data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
- data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
- data/ext/ffi_c/libffi/src/types.c +77 -0
- data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
- data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
- data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
- data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
- data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
- data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
- data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
- data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
- data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
- data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
- data/ext/ffi_c/libffi/texinfo.tex +7482 -0
- data/ext/ffi_c/rbffi.h +26 -0
- data/gen/Rakefile +12 -0
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/1.9/ffi_c.so +0 -0
- data/lib/ffi.rb +11 -0
- data/lib/ffi/autopointer.rb +61 -0
- data/lib/ffi/buffer.rb +0 -0
- data/lib/ffi/callback.rb +10 -0
- data/lib/ffi/enum.rb +78 -0
- data/lib/ffi/errno.rb +8 -0
- data/lib/ffi/ffi.rb +99 -0
- data/lib/ffi/io.rb +21 -0
- data/lib/ffi/library.rb +218 -0
- data/lib/ffi/managedstruct.rb +55 -0
- data/lib/ffi/memorypointer.rb +73 -0
- data/lib/ffi/platform.rb +88 -0
- data/lib/ffi/pointer.rb +119 -0
- data/lib/ffi/struct.rb +183 -0
- data/lib/ffi/tools/const_generator.rb +177 -0
- data/lib/ffi/tools/generator.rb +58 -0
- data/lib/ffi/tools/generator_task.rb +35 -0
- data/lib/ffi/tools/struct_generator.rb +194 -0
- data/lib/ffi/tools/types_generator.rb +123 -0
- data/lib/ffi/types.rb +153 -0
- data/lib/ffi/union.rb +12 -0
- data/lib/ffi/variadic.rb +25 -0
- data/spec/ffi/bool_spec.rb +24 -0
- data/spec/ffi/buffer_spec.rb +202 -0
- data/spec/ffi/callback_spec.rb +591 -0
- data/spec/ffi/enum_spec.rb +164 -0
- data/spec/ffi/errno_spec.rb +13 -0
- data/spec/ffi/function_spec.rb +73 -0
- data/spec/ffi/library_spec.rb +148 -0
- data/spec/ffi/managed_struct_spec.rb +56 -0
- data/spec/ffi/number_spec.rb +231 -0
- data/spec/ffi/pointer_spec.rb +195 -0
- data/spec/ffi/rbx/attach_function_spec.rb +27 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
- data/spec/ffi/rbx/spec_helper.rb +1 -0
- data/spec/ffi/rbx/struct_spec.rb +13 -0
- data/spec/ffi/spec_helper.rb +17 -0
- data/spec/ffi/string_spec.rb +103 -0
- data/spec/ffi/struct_callback_spec.rb +64 -0
- data/spec/ffi/struct_initialize_spec.rb +30 -0
- data/spec/ffi/struct_spec.rb +529 -0
- data/spec/ffi/typedef_spec.rb +48 -0
- data/spec/ffi/union_spec.rb +60 -0
- data/spec/ffi/variadic_spec.rb +84 -0
- data/spec/spec.opts +4 -0
- metadata +396 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module FFI
|
2
|
+
#
|
3
|
+
# FFI::ManagedStruct allows custom garbage-collection of your FFI::Structs.
|
4
|
+
#
|
5
|
+
# The typical use case would be when interacting with a library
|
6
|
+
# that has a nontrivial memory management design, such as a linked
|
7
|
+
# list or a binary tree.
|
8
|
+
#
|
9
|
+
# When the Struct instance is garbage collected, FFI::ManagedStruct will
|
10
|
+
# invoke the class's release() method during object finalization.
|
11
|
+
#
|
12
|
+
# Example usage:
|
13
|
+
# module MyLibrary
|
14
|
+
# ffi_lib "libmylibrary"
|
15
|
+
# attach_function :new_dlist, [], :pointer
|
16
|
+
# attach_function :destroy_dlist, [:pointer], :void
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# class DoublyLinkedList < FFI::ManagedStruct
|
20
|
+
# @@@
|
21
|
+
# struct do |s|
|
22
|
+
# s.name 'struct dlist'
|
23
|
+
# s.include 'dlist.h'
|
24
|
+
# s.field :head, :pointer
|
25
|
+
# s.field :tail, :pointer
|
26
|
+
# end
|
27
|
+
# @@@
|
28
|
+
#
|
29
|
+
# def self.release ptr
|
30
|
+
# MyLibrary.destroy_dlist(ptr)
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# begin
|
35
|
+
# ptr = DoublyLinkedList.new(MyLibrary.new_dlist)
|
36
|
+
# # do something with the list
|
37
|
+
# end
|
38
|
+
# # struct is out of scope, and will be GC'd using DoublyLinkedList#release
|
39
|
+
#
|
40
|
+
#
|
41
|
+
class ManagedStruct < FFI::Struct
|
42
|
+
|
43
|
+
# call-seq:
|
44
|
+
# ManagedStruct.new(pointer)
|
45
|
+
# ManagedStruct.new
|
46
|
+
#
|
47
|
+
# When passed a pointer, create a new ManagedStruct which will invoke the class method release() on
|
48
|
+
def initialize(pointer=nil)
|
49
|
+
raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to? :release
|
50
|
+
raise ArgumentError, "Must supply a pointer to memory for the Struct" unless pointer
|
51
|
+
super FFI::AutoPointer.new(pointer, self.class.method(:release))
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'ffi/pointer'
|
2
|
+
module FFI
|
3
|
+
class MemoryPointer
|
4
|
+
# call-seq:
|
5
|
+
# MemoryPointer.new(num) => MemoryPointer instance of <i>num</i> bytes
|
6
|
+
# MemoryPointer.new(sym) => MemoryPointer instance with number
|
7
|
+
# of bytes need by FFI type <i>sym</i>
|
8
|
+
# MemoryPointer.new(obj) => MemoryPointer instance with number
|
9
|
+
# of <i>obj.size</i> bytes
|
10
|
+
# MemoryPointer.new(sym, count) => MemoryPointer instance with number
|
11
|
+
# of bytes need by length-<i>count</i> array
|
12
|
+
# of FFI type <i>sym</i>
|
13
|
+
# MemoryPointer.new(obj, count) => MemoryPointer instance with number
|
14
|
+
# of bytes need by length-<i>count</i> array
|
15
|
+
# of <i>obj.size</i> bytes
|
16
|
+
# MemoryPointer.new(arg) { |p| ... }
|
17
|
+
#
|
18
|
+
# Both forms create a MemoryPointer instance. The number of bytes to
|
19
|
+
# allocate is either specified directly or by passing an FFI type, which
|
20
|
+
# specifies the number of bytes needed for that type.
|
21
|
+
#
|
22
|
+
# The form without a block returns the MemoryPointer instance. The form
|
23
|
+
# with a block yields the MemoryPointer instance and frees the memory
|
24
|
+
# when the block returns. The value returned is the value of the block.
|
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
|
47
|
+
def self.from_string(s)
|
48
|
+
ptr = self.new(s.length + 1, 1, false)
|
49
|
+
ptr.put_string(0, s)
|
50
|
+
ptr
|
51
|
+
end
|
52
|
+
# Indicates how many bytes the type that the pointer is cast as uses.
|
53
|
+
# attr_accessor :type_size
|
54
|
+
|
55
|
+
# Access the MemoryPointer like a C array, accessing the +which+ number
|
56
|
+
# element in memory. The position of the element is calculate from
|
57
|
+
# +@type_size+ and +which+. A new MemoryPointer object is returned, which
|
58
|
+
# points to the address of the element.
|
59
|
+
#
|
60
|
+
# Example:
|
61
|
+
# ptr = MemoryPointer.new(:int, 20)
|
62
|
+
# new_ptr = ptr[9]
|
63
|
+
#
|
64
|
+
# c-equiv:
|
65
|
+
# int *ptr = (int*)malloc(sizeof(int) * 20);
|
66
|
+
# int *new_ptr;
|
67
|
+
# new_ptr = &ptr[9];
|
68
|
+
#
|
69
|
+
# def [](which)
|
70
|
+
# self + (which * type_size)
|
71
|
+
# end
|
72
|
+
end
|
73
|
+
end
|
data/lib/ffi/platform.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
module FFI
|
3
|
+
class PlatformError < FFI::NativeError; end
|
4
|
+
|
5
|
+
module Platform
|
6
|
+
OS = case Config::CONFIG['host_os'].downcase
|
7
|
+
when /linux/
|
8
|
+
"linux"
|
9
|
+
when /darwin/
|
10
|
+
"darwin"
|
11
|
+
when /freebsd/
|
12
|
+
"freebsd"
|
13
|
+
when /openbsd/
|
14
|
+
"openbsd"
|
15
|
+
when /sunos|solaris/
|
16
|
+
"solaris"
|
17
|
+
when /win|mingw/
|
18
|
+
"windows"
|
19
|
+
else
|
20
|
+
Config::CONFIG['host_os'].downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
ARCH = case CPU.downcase
|
24
|
+
when /amd64|x86_64/
|
25
|
+
"x86_64"
|
26
|
+
when /i?86|x86|i86pc/
|
27
|
+
"i386"
|
28
|
+
when /ppc|powerpc/
|
29
|
+
"powerpc"
|
30
|
+
else
|
31
|
+
Config::CONFIG['host_cpu']
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def self.is_os(os)
|
36
|
+
OS == os
|
37
|
+
end
|
38
|
+
|
39
|
+
NAME = "#{ARCH}-#{OS}"
|
40
|
+
IS_LINUX = is_os("linux")
|
41
|
+
IS_MAC = is_os("darwin")
|
42
|
+
IS_FREEBSD = is_os("freebsd")
|
43
|
+
IS_OPENBSD = is_os("openbsd")
|
44
|
+
IS_WINDOWS = is_os("windows")
|
45
|
+
IS_BSD = IS_MAC || IS_FREEBSD || IS_OPENBSD
|
46
|
+
CONF_DIR = File.dirname(__FILE__)
|
47
|
+
public
|
48
|
+
|
49
|
+
LIBC = if IS_WINDOWS
|
50
|
+
"msvcrt"
|
51
|
+
elsif IS_LINUX
|
52
|
+
"libc.so.6"
|
53
|
+
else
|
54
|
+
"c"
|
55
|
+
end
|
56
|
+
|
57
|
+
LIBPREFIX = IS_WINDOWS ? '' : 'lib'
|
58
|
+
|
59
|
+
LIBSUFFIX = case OS
|
60
|
+
when /darwin/
|
61
|
+
'dylib'
|
62
|
+
when /linux|bsd|solaris/
|
63
|
+
'so'
|
64
|
+
when /windows/
|
65
|
+
'dll'
|
66
|
+
else
|
67
|
+
# Punt and just assume a sane unix (i.e. anything but AIX)
|
68
|
+
'so'
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.bsd?
|
72
|
+
IS_BSD
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.windows?
|
76
|
+
IS_WINDOWS
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.mac?
|
80
|
+
IS_MAC
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.unix?
|
84
|
+
!IS_WINDOWS
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
data/lib/ffi/pointer.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'ffi/platform'
|
2
|
+
module FFI
|
3
|
+
class Pointer
|
4
|
+
SIZE = Platform::ADDRESS_SIZE / 8
|
5
|
+
|
6
|
+
# Return the size of a pointer on the current platform, in bytes
|
7
|
+
def self.size
|
8
|
+
SIZE
|
9
|
+
end
|
10
|
+
# Write +obj+ as a C int at the memory pointed to.
|
11
|
+
def write_int(obj)
|
12
|
+
put_int32(0, obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Read a C int from the memory pointed to.
|
16
|
+
def read_int
|
17
|
+
get_int32(0)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Write +obj+ as a C long at the memory pointed to.
|
21
|
+
def write_long(obj)
|
22
|
+
put_long(0, obj)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Read a C long from the memory pointed to.
|
26
|
+
def read_long
|
27
|
+
get_long(0)
|
28
|
+
end
|
29
|
+
# Write +obj+ as a C long long at the memory pointed to.
|
30
|
+
def write_long_long(obj)
|
31
|
+
put_int64(0, obj)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Read a C long long from the memory pointed to.
|
35
|
+
def read_long_long
|
36
|
+
get_int64(0)
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_pointer
|
40
|
+
get_pointer(0)
|
41
|
+
end
|
42
|
+
def write_pointer(ptr)
|
43
|
+
put_pointer(0, ptr)
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_float
|
47
|
+
get_float32(0)
|
48
|
+
end
|
49
|
+
def write_float(obj)
|
50
|
+
put_float32(0, obj)
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_string(len=nil)
|
54
|
+
if len
|
55
|
+
get_bytes(0, len)
|
56
|
+
else
|
57
|
+
get_string(0)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
def read_string_length(len)
|
61
|
+
get_bytes(0, len)
|
62
|
+
end
|
63
|
+
def read_string_to_null
|
64
|
+
get_string(0)
|
65
|
+
end
|
66
|
+
def write_string_length(str, len)
|
67
|
+
put_bytes(0, str, 0, len)
|
68
|
+
end
|
69
|
+
def write_string(str, len=nil)
|
70
|
+
len = str.size unless len
|
71
|
+
# Write the string data without NUL termination
|
72
|
+
put_bytes(0, str, 0, len)
|
73
|
+
end
|
74
|
+
def read_array_of_type(type, reader, length)
|
75
|
+
ary = []
|
76
|
+
size = FFI.type_size(type)
|
77
|
+
tmp = self
|
78
|
+
length.times { |j|
|
79
|
+
ary << tmp.send(reader)
|
80
|
+
tmp += size unless j == length-1 # avoid OOB
|
81
|
+
}
|
82
|
+
ary
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_array_of_type(type, writer, ary)
|
86
|
+
size = FFI.type_size(type)
|
87
|
+
tmp = self
|
88
|
+
ary.each_with_index {|i, j|
|
89
|
+
tmp.send(writer, i)
|
90
|
+
tmp += size unless j == ary.length-1 # avoid OOB
|
91
|
+
}
|
92
|
+
self
|
93
|
+
end
|
94
|
+
def read_array_of_int(length)
|
95
|
+
get_array_of_int32(0, length)
|
96
|
+
end
|
97
|
+
|
98
|
+
def write_array_of_int(ary)
|
99
|
+
put_array_of_int32(0, ary)
|
100
|
+
end
|
101
|
+
|
102
|
+
def read_array_of_long(length)
|
103
|
+
get_array_of_long(0, length)
|
104
|
+
end
|
105
|
+
|
106
|
+
def write_array_of_long(ary)
|
107
|
+
put_array_of_long(0, ary)
|
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
|
+
|
118
|
+
end
|
119
|
+
end
|
data/lib/ffi/struct.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'ffi/platform'
|
2
|
+
module FFI
|
3
|
+
|
4
|
+
class StructLayout
|
5
|
+
|
6
|
+
def offsets
|
7
|
+
members.map { |m| [ m, self[m].offset ] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def offset_of(field_name)
|
11
|
+
self[field_name].offset
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class Struct
|
17
|
+
|
18
|
+
def size
|
19
|
+
self.class.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def alignment
|
23
|
+
self.class.alignment
|
24
|
+
end
|
25
|
+
alias_method :align, :alignment
|
26
|
+
|
27
|
+
def offset_of(name)
|
28
|
+
self.class.offset_of(name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def members
|
32
|
+
self.class.members
|
33
|
+
end
|
34
|
+
|
35
|
+
def values
|
36
|
+
members.map { |m| self[m] }
|
37
|
+
end
|
38
|
+
|
39
|
+
def offsets
|
40
|
+
self.class.offsets
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear
|
44
|
+
pointer.clear
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_ptr
|
49
|
+
pointer
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.size
|
53
|
+
defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.size=(size)
|
57
|
+
raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
|
58
|
+
@size = size
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.alignment
|
62
|
+
@layout.alignment
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.align
|
66
|
+
@layout.alignment
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.members
|
70
|
+
@layout.members
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.offsets
|
74
|
+
@layout.offsets
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.offset_of(name)
|
78
|
+
@layout.offset_of(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.in
|
82
|
+
:buffer_in
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.out
|
86
|
+
:buffer_out
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.by_value
|
90
|
+
::FFI::StructByValue.new(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
class << self
|
96
|
+
public
|
97
|
+
|
98
|
+
def layout(*spec)
|
99
|
+
return @layout if spec.size == 0
|
100
|
+
|
101
|
+
builder = FFI::StructLayoutBuilder.new
|
102
|
+
builder.union = self < Union
|
103
|
+
if spec[0].kind_of?(Hash)
|
104
|
+
hash_layout(builder, spec)
|
105
|
+
else
|
106
|
+
array_layout(builder, spec)
|
107
|
+
end
|
108
|
+
builder.size = @size if defined?(@size) && @size > builder.size
|
109
|
+
cspec = builder.build
|
110
|
+
@layout = cspec unless self == FFI::Struct
|
111
|
+
@size = cspec.size
|
112
|
+
return cspec
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
def callback(params, ret)
|
119
|
+
mod = enclosing_module
|
120
|
+
FFI::CallbackInfo.new(find_type(ret, mod), params.map { |e| find_type(e, mod) })
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def enclosing_module
|
125
|
+
begin
|
126
|
+
mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
|
127
|
+
mod.respond_to?(:find_type) ? mod : nil
|
128
|
+
rescue Exception => ex
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def find_type(type, mod = nil)
|
134
|
+
if (type.kind_of?(Class) && type < FFI::Struct) || type.is_a?(::Array)
|
135
|
+
type
|
136
|
+
elsif mod
|
137
|
+
mod.find_type(type)
|
138
|
+
end || FFI.find_type(type)
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def hash_layout(builder, spec)
|
145
|
+
raise "Ruby version not supported" if RUBY_VERSION =~ /1.8.*/
|
146
|
+
mod = enclosing_module
|
147
|
+
spec[0].each do |name,type|
|
148
|
+
if type.kind_of?(Class) && type < Struct
|
149
|
+
builder.add_struct(name, type)
|
150
|
+
elsif type.kind_of?(::Array)
|
151
|
+
builder.add_array(name, find_type(type[0], mod), type[1])
|
152
|
+
else
|
153
|
+
builder.add_field(name, find_type(type, mod))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def array_layout(builder, spec)
|
159
|
+
mod = enclosing_module
|
160
|
+
i = 0
|
161
|
+
while i < spec.size
|
162
|
+
name, type = spec[i, 2]
|
163
|
+
i += 2
|
164
|
+
|
165
|
+
# If the next param is a Integer, it specifies the offset
|
166
|
+
if spec[i].kind_of?(Integer)
|
167
|
+
offset = spec[i]
|
168
|
+
i += 1
|
169
|
+
else
|
170
|
+
offset = nil
|
171
|
+
end
|
172
|
+
if type.kind_of?(Class) && type < Struct
|
173
|
+
builder.add_struct(name, type, offset)
|
174
|
+
elsif type.kind_of?(::Array)
|
175
|
+
builder.add_array(name, find_type(type[0], mod), type[1], offset)
|
176
|
+
else
|
177
|
+
builder.add_field(name, find_type(type, mod), offset)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|