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
data/ext/ffi_c/Call.h
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2009, Wayne Meissner
|
3
|
+
* Copyright (c) 2009, Luc Heinrich <luc@honk-honk.com>
|
4
|
+
* Copyright (c) 2009, Mike Dalessio <mike.dalessio@gmail.com>
|
5
|
+
* Copyright (c) 2009, Aman Gupta.
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
*
|
11
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
12
|
+
* list of conditions and the following disclaimer.
|
13
|
+
* * Redistributions in binary form must reproduce the above copyright notice
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
15
|
+
* and/or other materials provided with the distribution.
|
16
|
+
* * The name of the author or authors may not be used to endorse or promote
|
17
|
+
* products derived from this software without specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
23
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#ifndef _INVOKE_H
|
32
|
+
#define _INVOKE_H
|
33
|
+
|
34
|
+
#ifdef __cplusplus
|
35
|
+
extern "C" {
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#if defined(__i386__) && !defined(_WIN32) && !defined(__WIN32__)
|
39
|
+
# define USE_RAW
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#if (defined(__i386__) || defined(__x86_64__)) && !(defined(_WIN32) || defined(__WIN32__))
|
43
|
+
# define BYPASS_FFI 1
|
44
|
+
#endif
|
45
|
+
|
46
|
+
typedef union {
|
47
|
+
#ifdef USE_RAW
|
48
|
+
signed int s8, s16, s32;
|
49
|
+
unsigned int u8, u16, u32;
|
50
|
+
#else
|
51
|
+
signed char s8;
|
52
|
+
unsigned char u8;
|
53
|
+
signed short s16;
|
54
|
+
unsigned short u16;
|
55
|
+
signed int s32;
|
56
|
+
unsigned int u32;
|
57
|
+
#endif
|
58
|
+
signed long long i64;
|
59
|
+
unsigned long long u64;
|
60
|
+
void* ptr;
|
61
|
+
float f32;
|
62
|
+
double f64;
|
63
|
+
} FFIStorage;
|
64
|
+
|
65
|
+
|
66
|
+
extern void rbffi_Call_Init(VALUE moduleFFI);
|
67
|
+
|
68
|
+
extern void rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTypes,
|
69
|
+
FFIStorage* paramStorage, void** ffiValues,
|
70
|
+
VALUE* callbackParameters, int callbackCount, VALUE enums);
|
71
|
+
|
72
|
+
extern VALUE rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
|
73
|
+
|
74
|
+
typedef VALUE (*Invoker)(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
|
75
|
+
|
76
|
+
Invoker rbffi_GetInvoker(FunctionType* fnInfo);
|
77
|
+
|
78
|
+
extern VALUE rbffi_GetEnumValue(VALUE enums, VALUE value);
|
79
|
+
extern int rbffi_GetSignedIntValue(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums);
|
80
|
+
|
81
|
+
#ifdef __cplusplus
|
82
|
+
}
|
83
|
+
#endif
|
84
|
+
|
85
|
+
#endif /* _INVOKE_H */
|
86
|
+
|
@@ -0,0 +1,302 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2009, Wayne Meissner
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
9
|
+
* list of conditions and the following disclaimer.
|
10
|
+
* * Redistributions in binary form must reproduce the above copyright notice
|
11
|
+
* this list of conditions and the following disclaimer in the documentation
|
12
|
+
* and/or other materials provided with the distribution.
|
13
|
+
* * The name of the author or authors may not be used to endorse or promote
|
14
|
+
* products derived from this software without specific prior written permission.
|
15
|
+
*
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
20
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
*/
|
27
|
+
|
28
|
+
#include <sys/param.h>
|
29
|
+
#include <sys/types.h>
|
30
|
+
#ifndef _WIN32
|
31
|
+
# include <sys/mman.h>
|
32
|
+
#endif
|
33
|
+
#include <stdio.h>
|
34
|
+
#include <stdint.h>
|
35
|
+
#include <stdbool.h>
|
36
|
+
#ifndef _WIN32
|
37
|
+
# include <unistd.h>
|
38
|
+
#endif
|
39
|
+
#include <errno.h>
|
40
|
+
#include <ruby.h>
|
41
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
|
42
|
+
# include <pthread.h>
|
43
|
+
#endif
|
44
|
+
|
45
|
+
#include <ffi.h>
|
46
|
+
#include "rbffi.h"
|
47
|
+
#include "compat.h"
|
48
|
+
|
49
|
+
#include "Function.h"
|
50
|
+
#include "Types.h"
|
51
|
+
#include "Type.h"
|
52
|
+
#include "LastError.h"
|
53
|
+
#include "Call.h"
|
54
|
+
|
55
|
+
#include "ClosurePool.h"
|
56
|
+
|
57
|
+
|
58
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
|
59
|
+
# define USE_PTHREAD_LOCAL
|
60
|
+
#endif
|
61
|
+
|
62
|
+
#ifndef roundup
|
63
|
+
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
64
|
+
#endif
|
65
|
+
#ifdef _WIN32
|
66
|
+
typedef char* caddr_t;
|
67
|
+
#endif
|
68
|
+
|
69
|
+
typedef struct Memory {
|
70
|
+
void* code;
|
71
|
+
void* data;
|
72
|
+
struct Memory* next;
|
73
|
+
} Memory;
|
74
|
+
|
75
|
+
struct ClosurePool_ {
|
76
|
+
void* ctx;
|
77
|
+
int closureSize;
|
78
|
+
bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize);
|
79
|
+
#if defined (HAVE_NATIVETHREAD) && !defined(_WIN32)
|
80
|
+
pthread_mutex_t mutex;
|
81
|
+
#endif
|
82
|
+
struct Memory* blocks; /* Keeps track of all the allocated memory for this pool */
|
83
|
+
Closure* list;
|
84
|
+
long refcnt;
|
85
|
+
};
|
86
|
+
|
87
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
|
88
|
+
# define pool_lock(p) pthread_mutex_lock(&(p)->mutex)
|
89
|
+
# define pool_unlock(p) pthread_mutex_unlock(&(p)->mutex)
|
90
|
+
#else
|
91
|
+
# define pool_lock(p)
|
92
|
+
# define pool_unlock(p)
|
93
|
+
#endif
|
94
|
+
|
95
|
+
static int pageSize;
|
96
|
+
|
97
|
+
static void* allocatePage(void);
|
98
|
+
static bool freePage(void *);
|
99
|
+
static bool protectPage(void *);
|
100
|
+
|
101
|
+
ClosurePool*
|
102
|
+
rbffi_ClosurePool_New(int closureSize,
|
103
|
+
bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
|
104
|
+
void* ctx)
|
105
|
+
{
|
106
|
+
ClosurePool* pool;
|
107
|
+
|
108
|
+
pool = xcalloc(1, sizeof(*pool));
|
109
|
+
pool->closureSize = closureSize;
|
110
|
+
pool->ctx = ctx;
|
111
|
+
pool->prep = prep;
|
112
|
+
pool->refcnt = 1;
|
113
|
+
|
114
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
|
115
|
+
pthread_mutex_init(&pool->mutex, NULL);
|
116
|
+
#endif
|
117
|
+
|
118
|
+
return pool;
|
119
|
+
}
|
120
|
+
|
121
|
+
void
|
122
|
+
cleanup_closure_pool(ClosurePool* pool)
|
123
|
+
{
|
124
|
+
Memory* memory;
|
125
|
+
|
126
|
+
for (memory = pool->blocks; memory != NULL; ) {
|
127
|
+
Memory* next = memory->next;
|
128
|
+
freePage(memory->code);
|
129
|
+
free(memory->data);
|
130
|
+
free(memory);
|
131
|
+
memory = next;
|
132
|
+
}
|
133
|
+
free(pool);
|
134
|
+
}
|
135
|
+
|
136
|
+
void
|
137
|
+
rbffi_ClosurePool_Free(ClosurePool* pool)
|
138
|
+
{
|
139
|
+
if (pool != NULL) {
|
140
|
+
int refcnt;
|
141
|
+
pool_lock(pool);
|
142
|
+
refcnt = --(pool->refcnt);
|
143
|
+
pool_unlock(pool);
|
144
|
+
|
145
|
+
if (refcnt == 0) {
|
146
|
+
cleanup_closure_pool(pool);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
Closure*
|
152
|
+
rbffi_Closure_Alloc(ClosurePool* pool)
|
153
|
+
{
|
154
|
+
Closure *list = NULL;
|
155
|
+
Memory* block = NULL;
|
156
|
+
caddr_t code = NULL;
|
157
|
+
char errmsg[256];
|
158
|
+
int nclosures, trampolineSize;
|
159
|
+
int i;
|
160
|
+
|
161
|
+
pool_lock(pool);
|
162
|
+
if (pool->list != NULL) {
|
163
|
+
Closure* closure = pool->list;
|
164
|
+
pool->list = pool->list->next;
|
165
|
+
pool->refcnt++;
|
166
|
+
pool_unlock(pool);
|
167
|
+
|
168
|
+
return closure;
|
169
|
+
}
|
170
|
+
|
171
|
+
trampolineSize = roundup(pool->closureSize, 8);
|
172
|
+
nclosures = pageSize / trampolineSize;
|
173
|
+
block = calloc(1, sizeof(*block));
|
174
|
+
list = calloc(nclosures, sizeof(*list));
|
175
|
+
code = allocatePage();
|
176
|
+
|
177
|
+
if (block == NULL || list == NULL || code == NULL) {
|
178
|
+
pool_unlock(pool);
|
179
|
+
snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
|
180
|
+
goto error;
|
181
|
+
}
|
182
|
+
|
183
|
+
for (i = 0; i < nclosures; ++i) {
|
184
|
+
Closure* closure = &list[i];
|
185
|
+
closure->next = &list[i + 1];
|
186
|
+
closure->pool = pool;
|
187
|
+
closure->code = (code + (i * trampolineSize));
|
188
|
+
|
189
|
+
if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
|
190
|
+
goto error;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
if (!protectPage(code)) {
|
195
|
+
goto error;
|
196
|
+
}
|
197
|
+
|
198
|
+
/* Track the allocated page + Closure memory area */
|
199
|
+
block->data = list;
|
200
|
+
block->code = code;
|
201
|
+
block->next = pool->blocks;
|
202
|
+
pool->blocks = block;
|
203
|
+
|
204
|
+
/* Thread the new block onto the free list, apart from the first one. */
|
205
|
+
list[nclosures - 1].next = pool->list;
|
206
|
+
pool->list = list->next;
|
207
|
+
pool->refcnt++;
|
208
|
+
|
209
|
+
pool_unlock(pool);
|
210
|
+
|
211
|
+
/* Use the first one as the new handle */
|
212
|
+
return list;
|
213
|
+
|
214
|
+
error:
|
215
|
+
pool_unlock(pool);
|
216
|
+
free(block);
|
217
|
+
free(list);
|
218
|
+
if (code != NULL) {
|
219
|
+
freePage(code);
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
rb_raise(rb_eRuntimeError, "%s", errmsg);
|
224
|
+
return NULL;
|
225
|
+
}
|
226
|
+
|
227
|
+
void
|
228
|
+
rbffi_Closure_Free(Closure* closure)
|
229
|
+
{
|
230
|
+
if (closure != NULL) {
|
231
|
+
ClosurePool* pool = closure->pool;
|
232
|
+
int refcnt;
|
233
|
+
pool_lock(pool);
|
234
|
+
// Just push it on the front of the free list
|
235
|
+
closure->next = pool->list;
|
236
|
+
pool->list = closure;
|
237
|
+
refcnt = --(pool->refcnt);
|
238
|
+
pool_unlock(pool);
|
239
|
+
|
240
|
+
if (refcnt == 0) {
|
241
|
+
cleanup_closure_pool(pool);
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
void*
|
247
|
+
rbffi_Closure_CodeAddress(Closure* handle)
|
248
|
+
{
|
249
|
+
return handle->code;
|
250
|
+
}
|
251
|
+
|
252
|
+
|
253
|
+
static int
|
254
|
+
getPageSize()
|
255
|
+
{
|
256
|
+
#ifdef _WIN32
|
257
|
+
SYSTEM_INFO si;
|
258
|
+
GetSystemInfo(&si);
|
259
|
+
return si.dwPageSize;
|
260
|
+
#else
|
261
|
+
return sysconf(_SC_PAGESIZE);
|
262
|
+
#endif
|
263
|
+
}
|
264
|
+
|
265
|
+
static void*
|
266
|
+
allocatePage(void)
|
267
|
+
{
|
268
|
+
#ifdef _WIN32
|
269
|
+
return VirtualAlloc(NULL, pageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
270
|
+
#else
|
271
|
+
caddr_t page = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
272
|
+
return (page != (caddr_t) -1) ? page : NULL;
|
273
|
+
#endif
|
274
|
+
}
|
275
|
+
|
276
|
+
static bool
|
277
|
+
freePage(void *addr)
|
278
|
+
{
|
279
|
+
#ifdef _WIN32
|
280
|
+
return VirtualFree(addr, 0, MEM_RELEASE);
|
281
|
+
#else
|
282
|
+
return munmap(addr, pageSize) == 0;
|
283
|
+
#endif
|
284
|
+
}
|
285
|
+
|
286
|
+
static bool
|
287
|
+
protectPage(void* page)
|
288
|
+
{
|
289
|
+
#ifdef _WIN32
|
290
|
+
DWORD oldProtect;
|
291
|
+
return VirtualProtect(page, pageSize, PAGE_EXECUTE_READ, &oldProtect);
|
292
|
+
#else
|
293
|
+
return mprotect(page, pageSize, PROT_READ | PROT_EXEC) == 0;
|
294
|
+
#endif
|
295
|
+
}
|
296
|
+
|
297
|
+
void
|
298
|
+
rbffi_ClosurePool_Init(VALUE module)
|
299
|
+
{
|
300
|
+
pageSize = getPageSize();
|
301
|
+
}
|
302
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#ifndef RUBYFFI_CLOSUREPOOL_H
|
2
|
+
#define RUBYFFI_CLOSUREPOOL_H
|
3
|
+
|
4
|
+
typedef struct ClosurePool_ ClosurePool;
|
5
|
+
typedef struct Closure_ Closure;
|
6
|
+
|
7
|
+
struct Closure_ {
|
8
|
+
void* info; /* opaque handle for storing closure-instance specific data */
|
9
|
+
void* function; /* closure-instance specific function, called by custom trampoline */
|
10
|
+
void* code; /* The native trampoline code location */
|
11
|
+
struct ClosurePool_* pool;
|
12
|
+
Closure* next;
|
13
|
+
};
|
14
|
+
|
15
|
+
void rbffi_ClosurePool_Init(VALUE module);
|
16
|
+
|
17
|
+
ClosurePool* rbffi_ClosurePool_New(int closureSize,
|
18
|
+
bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
|
19
|
+
void* ctx);
|
20
|
+
|
21
|
+
void rbffi_ClosurePool_Free(ClosurePool *);
|
22
|
+
|
23
|
+
Closure* rbffi_Closure_Alloc(ClosurePool *);
|
24
|
+
void rbffi_Closure_Free(Closure *);
|
25
|
+
|
26
|
+
void* rbffi_Closure_GetCodeAddress(Closure *);
|
27
|
+
|
28
|
+
#endif /* RUBYFFI_CLOSUREPOOL_H */
|
29
|
+
|
@@ -0,0 +1,216 @@
|
|
1
|
+
#include <sys/types.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
#if defined(_WIN32) || defined(__WIN32__)
|
5
|
+
# include <windows.h>
|
6
|
+
#else
|
7
|
+
# include <dlfcn.h>
|
8
|
+
#endif
|
9
|
+
#include <ruby.h>
|
10
|
+
|
11
|
+
#include <ffi.h>
|
12
|
+
|
13
|
+
#include "rbffi.h"
|
14
|
+
#include "compat.h"
|
15
|
+
#include "AbstractMemory.h"
|
16
|
+
#include "Pointer.h"
|
17
|
+
#include "DynamicLibrary.h"
|
18
|
+
|
19
|
+
typedef struct LibrarySymbol_ {
|
20
|
+
AbstractMemory memory;
|
21
|
+
VALUE library;
|
22
|
+
VALUE name;
|
23
|
+
} LibrarySymbol;
|
24
|
+
|
25
|
+
static VALUE library_initialize(VALUE self, VALUE libname, VALUE libflags);
|
26
|
+
static void library_free(Library* lib);
|
27
|
+
|
28
|
+
|
29
|
+
static VALUE symbol_allocate(VALUE klass);
|
30
|
+
static VALUE symbol_new(VALUE library, void* address, VALUE name);
|
31
|
+
static void symbol_mark(LibrarySymbol* sym);
|
32
|
+
|
33
|
+
static VALUE LibraryClass = Qnil, SymbolClass = Qnil;
|
34
|
+
|
35
|
+
#if defined(_WIN32) || defined(__WIN32__)
|
36
|
+
static void* dl_open(const char* name, int flags);
|
37
|
+
static void dl_error(char* buf, int size);
|
38
|
+
#define dl_sym(handle, name) GetProcAddress(handle, name)
|
39
|
+
#define dl_close(handle) FreeLibrary(handle)
|
40
|
+
enum { RTLD_LAZY=1, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL };
|
41
|
+
#else
|
42
|
+
# define dl_open(name, flags) dlopen(name, flags != 0 ? flags : RTLD_LAZY)
|
43
|
+
# define dl_error(buf, size) do { snprintf(buf, size, "%s", dlerror()); } while(0)
|
44
|
+
# define dl_sym(handle, name) dlsym(handle, name)
|
45
|
+
# define dl_close(handle) dlclose(handle)
|
46
|
+
#ifndef RTLD_LOCAL
|
47
|
+
# define RTLD_LOCAL 8
|
48
|
+
#endif
|
49
|
+
#endif
|
50
|
+
|
51
|
+
static VALUE
|
52
|
+
library_allocate(VALUE klass)
|
53
|
+
{
|
54
|
+
Library* library;
|
55
|
+
return Data_Make_Struct(klass, Library, NULL, library_free, library);
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE
|
59
|
+
library_open(VALUE klass, VALUE libname, VALUE libflags)
|
60
|
+
{
|
61
|
+
return library_initialize(library_allocate(klass), libname, libflags);
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE
|
65
|
+
library_initialize(VALUE self, VALUE libname, VALUE libflags)
|
66
|
+
{
|
67
|
+
Library* library;
|
68
|
+
int flags;
|
69
|
+
|
70
|
+
Check_Type(libflags, T_FIXNUM);
|
71
|
+
|
72
|
+
Data_Get_Struct(self, Library, library);
|
73
|
+
flags = libflags != Qnil ? NUM2UINT(libflags) : 0;
|
74
|
+
|
75
|
+
library->handle = dl_open(libname != Qnil ? StringValueCStr(libname) : NULL, flags);
|
76
|
+
if (library->handle == NULL) {
|
77
|
+
char errmsg[1024];
|
78
|
+
dl_error(errmsg, sizeof(errmsg));
|
79
|
+
rb_raise(rb_eLoadError, "Could not open library '%s': %s",
|
80
|
+
libname != Qnil ? StringValueCStr(libname) : "[current process]",
|
81
|
+
errmsg);
|
82
|
+
}
|
83
|
+
rb_iv_set(self, "@name", libname != Qnil ? libname : rb_str_new2("[current process]"));
|
84
|
+
return self;
|
85
|
+
}
|
86
|
+
|
87
|
+
static VALUE
|
88
|
+
library_dlsym(VALUE self, VALUE name)
|
89
|
+
{
|
90
|
+
Library* library;
|
91
|
+
void* address = NULL;
|
92
|
+
Check_Type(name, T_STRING);
|
93
|
+
|
94
|
+
Data_Get_Struct(self, Library, library);
|
95
|
+
address = dl_sym(library->handle, StringValueCStr(name));
|
96
|
+
|
97
|
+
return address != NULL ? symbol_new(self, address, name) : Qnil;
|
98
|
+
}
|
99
|
+
|
100
|
+
static VALUE
|
101
|
+
library_dlerror(VALUE self)
|
102
|
+
{
|
103
|
+
char errmsg[1024];
|
104
|
+
dl_error(errmsg, sizeof(errmsg));
|
105
|
+
return rb_tainted_str_new2(errmsg);
|
106
|
+
}
|
107
|
+
|
108
|
+
static void
|
109
|
+
library_free(Library* library)
|
110
|
+
{
|
111
|
+
// dlclose() on MacOS tends to segfault - avoid it
|
112
|
+
#ifndef __APPLE__
|
113
|
+
if (library->handle != NULL) {
|
114
|
+
dl_close(library->handle);
|
115
|
+
}
|
116
|
+
#endif
|
117
|
+
xfree(library);
|
118
|
+
}
|
119
|
+
|
120
|
+
#if defined(_WIN32) || defined(__WIN32__)
|
121
|
+
static void*
|
122
|
+
dl_open(const char* name, int flags)
|
123
|
+
{
|
124
|
+
if (name == NULL) {
|
125
|
+
return GetModuleHandle(NULL);
|
126
|
+
} else {
|
127
|
+
return LoadLibraryEx(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
static void
|
132
|
+
dl_error(char* buf, int size)
|
133
|
+
{
|
134
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
135
|
+
0, buf, size, NULL);
|
136
|
+
}
|
137
|
+
#endif
|
138
|
+
|
139
|
+
static VALUE
|
140
|
+
symbol_allocate(VALUE klass)
|
141
|
+
{
|
142
|
+
LibrarySymbol* sym;
|
143
|
+
VALUE obj = Data_Make_Struct(klass, LibrarySymbol, NULL, -1, sym);
|
144
|
+
sym->name = Qnil;
|
145
|
+
sym->library = Qnil;
|
146
|
+
|
147
|
+
return obj;
|
148
|
+
}
|
149
|
+
|
150
|
+
static VALUE
|
151
|
+
symbol_new(VALUE library, void* address, VALUE name)
|
152
|
+
{
|
153
|
+
LibrarySymbol* sym;
|
154
|
+
VALUE obj = Data_Make_Struct(SymbolClass, LibrarySymbol, symbol_mark, -1, sym);
|
155
|
+
|
156
|
+
sym->memory.address = address;
|
157
|
+
sym->memory.size = LONG_MAX;
|
158
|
+
sym->memory.typeSize = 1;
|
159
|
+
sym->memory.access = MEM_RD | MEM_WR;
|
160
|
+
sym->memory.ops = &rbffi_AbstractMemoryOps;
|
161
|
+
sym->library = library;
|
162
|
+
sym->name = name;
|
163
|
+
|
164
|
+
return obj;
|
165
|
+
}
|
166
|
+
|
167
|
+
static void
|
168
|
+
symbol_mark(LibrarySymbol* sym)
|
169
|
+
{
|
170
|
+
rb_gc_mark(sym->library);
|
171
|
+
rb_gc_mark(sym->name);
|
172
|
+
}
|
173
|
+
|
174
|
+
static VALUE
|
175
|
+
symbol_inspect(VALUE self)
|
176
|
+
{
|
177
|
+
LibrarySymbol* sym;
|
178
|
+
char buf[256];
|
179
|
+
|
180
|
+
Data_Get_Struct(self, LibrarySymbol, sym);
|
181
|
+
snprintf(buf, sizeof(buf), "#<FFI::Library::Symbol name=%s address=%p>",
|
182
|
+
StringValueCStr(sym->name), sym->memory.address);
|
183
|
+
return rb_str_new2(buf);
|
184
|
+
}
|
185
|
+
|
186
|
+
void
|
187
|
+
rbffi_DynamicLibrary_Init(VALUE moduleFFI)
|
188
|
+
{
|
189
|
+
LibraryClass = rb_define_class_under(moduleFFI, "DynamicLibrary", rb_cObject);
|
190
|
+
rb_global_variable(&LibraryClass);
|
191
|
+
SymbolClass = rb_define_class_under(LibraryClass, "Symbol", rbffi_PointerClass);
|
192
|
+
rb_global_variable(&SymbolClass);
|
193
|
+
|
194
|
+
rb_define_const(moduleFFI, "NativeLibrary", LibraryClass); // backwards compat library
|
195
|
+
rb_define_alloc_func(LibraryClass, library_allocate);
|
196
|
+
rb_define_singleton_method(LibraryClass, "open", library_open, 2);
|
197
|
+
rb_define_singleton_method(LibraryClass, "last_error", library_dlerror, 0);
|
198
|
+
rb_define_method(LibraryClass, "initialize", library_initialize, 2);
|
199
|
+
rb_define_method(LibraryClass, "find_symbol", library_dlsym, 1);
|
200
|
+
rb_define_method(LibraryClass, "find_function", library_dlsym, 1);
|
201
|
+
rb_define_method(LibraryClass, "find_variable", library_dlsym, 1);
|
202
|
+
rb_define_method(LibraryClass, "last_error", library_dlerror, 0);
|
203
|
+
rb_define_attr(LibraryClass, "name", 1, 0);
|
204
|
+
|
205
|
+
rb_define_alloc_func(SymbolClass, symbol_allocate);
|
206
|
+
rb_undef_method(SymbolClass, "new");
|
207
|
+
rb_define_method(SymbolClass, "inspect", symbol_inspect, 0);
|
208
|
+
|
209
|
+
#define DEF(x) rb_define_const(LibraryClass, "RTLD_" #x, UINT2NUM(RTLD_##x))
|
210
|
+
DEF(LAZY);
|
211
|
+
DEF(NOW);
|
212
|
+
DEF(GLOBAL);
|
213
|
+
DEF(LOCAL);
|
214
|
+
|
215
|
+
}
|
216
|
+
|