ffi 0.1.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/LICENSE +51 -0
- data/README +0 -0
- data/Rakefile +90 -0
- data/ext/AbstractMemory.c +254 -0
- data/ext/AbstractMemory.h +36 -0
- data/ext/Buffer.c +94 -0
- data/ext/Callback.c +240 -0
- data/ext/Callback.h +47 -0
- data/ext/Invoker.c +269 -0
- data/ext/MemoryPointer.c +164 -0
- data/ext/MemoryPointer.h +25 -0
- data/ext/Platform.c +41 -0
- data/ext/Platform.h +23 -0
- data/ext/Types.c +65 -0
- data/ext/Types.h +51 -0
- data/ext/extconf.rb +13 -0
- data/ext/ffi.c +54 -0
- data/ext/ffi.mk +24 -0
- data/ext/libffi.darwin.mk +44 -0
- data/ext/libffi.mk +10 -0
- data/ext/libffi/ChangeLog +3243 -0
- data/ext/libffi/ChangeLog.libffi +347 -0
- data/ext/libffi/ChangeLog.libgcj +40 -0
- data/ext/libffi/ChangeLog.v1 +764 -0
- data/ext/libffi/LICENSE +21 -0
- data/ext/libffi/Makefile.am +177 -0
- data/ext/libffi/Makefile.in +1640 -0
- data/ext/libffi/README +328 -0
- data/ext/libffi/TODO +1 -0
- data/ext/libffi/acinclude.m4 +92 -0
- data/ext/libffi/aclocal.m4 +7516 -0
- data/ext/libffi/compile +142 -0
- data/ext/libffi/config.guess +1516 -0
- data/ext/libffi/config.sub +1626 -0
- data/ext/libffi/configure +24414 -0
- data/ext/libffi/configure.ac +365 -0
- data/ext/libffi/configure.host +11 -0
- data/ext/libffi/depcomp +584 -0
- data/ext/libffi/doc/libffi.info +533 -0
- data/ext/libffi/doc/libffi.texi +541 -0
- data/ext/libffi/doc/stamp-vti +4 -0
- data/ext/libffi/doc/version.texi +4 -0
- data/ext/libffi/fficonfig.h.in +160 -0
- data/ext/libffi/include/Makefile.am +9 -0
- data/ext/libffi/include/Makefile.in +422 -0
- data/ext/libffi/include/ffi.h.in +393 -0
- data/ext/libffi/include/ffi_common.h +98 -0
- data/ext/libffi/install-sh +323 -0
- data/ext/libffi/libffi.pc.in +10 -0
- data/ext/libffi/libtool-version +29 -0
- data/ext/libffi/ltcf-c.sh +861 -0
- data/ext/libffi/ltcf-cxx.sh +1069 -0
- data/ext/libffi/ltcf-gcj.sh +700 -0
- data/ext/libffi/ltconfig +2862 -0
- data/ext/libffi/ltmain.sh +6930 -0
- data/ext/libffi/man/Makefile.am +8 -0
- data/ext/libffi/man/Makefile.in +395 -0
- data/ext/libffi/man/ffi.3 +31 -0
- data/ext/libffi/man/ffi_call.3 +103 -0
- data/ext/libffi/man/ffi_prep_cif.3 +66 -0
- data/ext/libffi/mdate-sh +201 -0
- data/ext/libffi/missing +353 -0
- data/ext/libffi/mkinstalldirs +158 -0
- data/ext/libffi/src/alpha/ffi.c +284 -0
- data/ext/libffi/src/alpha/ffitarget.h +48 -0
- data/ext/libffi/src/alpha/osf.S +366 -0
- data/ext/libffi/src/arm/ffi.c +309 -0
- data/ext/libffi/src/arm/ffitarget.h +49 -0
- data/ext/libffi/src/arm/sysv.S +299 -0
- data/ext/libffi/src/closures.c +596 -0
- data/ext/libffi/src/cris/ffi.c +383 -0
- data/ext/libffi/src/cris/ffitarget.h +51 -0
- data/ext/libffi/src/cris/sysv.S +215 -0
- data/ext/libffi/src/debug.c +59 -0
- data/ext/libffi/src/dlmalloc.c +5099 -0
- data/ext/libffi/src/frv/eabi.S +128 -0
- data/ext/libffi/src/frv/ffi.c +292 -0
- data/ext/libffi/src/frv/ffitarget.h +61 -0
- data/ext/libffi/src/ia64/ffi.c +580 -0
- data/ext/libffi/src/ia64/ffitarget.h +50 -0
- data/ext/libffi/src/ia64/ia64_flags.h +40 -0
- data/ext/libffi/src/ia64/unix.S +560 -0
- data/ext/libffi/src/java_raw_api.c +359 -0
- data/ext/libffi/src/m32r/ffi.c +232 -0
- data/ext/libffi/src/m32r/ffitarget.h +48 -0
- data/ext/libffi/src/m32r/sysv.S +121 -0
- data/ext/libffi/src/m68k/ffi.c +278 -0
- data/ext/libffi/src/m68k/ffitarget.h +49 -0
- data/ext/libffi/src/m68k/sysv.S +234 -0
- data/ext/libffi/src/mips/ffi.c +926 -0
- data/ext/libffi/src/mips/ffitarget.h +202 -0
- data/ext/libffi/src/mips/n32.S +534 -0
- data/ext/libffi/src/mips/o32.S +381 -0
- data/ext/libffi/src/pa/ffi.c +709 -0
- data/ext/libffi/src/pa/ffitarget.h +77 -0
- data/ext/libffi/src/pa/hpux32.S +368 -0
- data/ext/libffi/src/pa/linux.S +357 -0
- data/ext/libffi/src/powerpc/aix.S +225 -0
- data/ext/libffi/src/powerpc/aix_closure.S +247 -0
- data/ext/libffi/src/powerpc/asm.h +125 -0
- data/ext/libffi/src/powerpc/darwin.S +245 -0
- data/ext/libffi/src/powerpc/darwin_closure.S +317 -0
- data/ext/libffi/src/powerpc/ffi.c +1429 -0
- data/ext/libffi/src/powerpc/ffi_darwin.c +800 -0
- data/ext/libffi/src/powerpc/ffitarget.h +118 -0
- data/ext/libffi/src/powerpc/linux64.S +187 -0
- data/ext/libffi/src/powerpc/linux64_closure.S +236 -0
- data/ext/libffi/src/powerpc/ppc_closure.S +327 -0
- data/ext/libffi/src/powerpc/sysv.S +230 -0
- data/ext/libffi/src/prep_cif.c +174 -0
- data/ext/libffi/src/raw_api.c +254 -0
- data/ext/libffi/src/s390/ffi.c +780 -0
- data/ext/libffi/src/s390/ffitarget.h +60 -0
- data/ext/libffi/src/s390/sysv.S +434 -0
- data/ext/libffi/src/sh/ffi.c +716 -0
- data/ext/libffi/src/sh/ffitarget.h +49 -0
- data/ext/libffi/src/sh/sysv.S +850 -0
- data/ext/libffi/src/sh64/ffi.c +453 -0
- data/ext/libffi/src/sh64/ffitarget.h +53 -0
- data/ext/libffi/src/sh64/sysv.S +530 -0
- data/ext/libffi/src/sparc/ffi.c +610 -0
- data/ext/libffi/src/sparc/ffitarget.h +66 -0
- data/ext/libffi/src/sparc/v8.S +272 -0
- data/ext/libffi/src/sparc/v9.S +307 -0
- data/ext/libffi/src/types.c +77 -0
- data/ext/libffi/src/x86/darwin.S +443 -0
- data/ext/libffi/src/x86/darwin64.S +416 -0
- data/ext/libffi/src/x86/ffi.c +475 -0
- data/ext/libffi/src/x86/ffi64.c +572 -0
- data/ext/libffi/src/x86/ffitarget.h +90 -0
- data/ext/libffi/src/x86/freebsd.S +458 -0
- data/ext/libffi/src/x86/sysv.S +437 -0
- data/ext/libffi/src/x86/unix64.S +418 -0
- data/ext/libffi/src/x86/win32.S +391 -0
- data/ext/libffi/testsuite/Makefile.am +71 -0
- data/ext/libffi/testsuite/Makefile.in +447 -0
- data/ext/libffi/testsuite/config/default.exp +1 -0
- data/ext/libffi/testsuite/lib/libffi-dg.exp +289 -0
- data/ext/libffi/testsuite/lib/target-libpath.exp +263 -0
- data/ext/libffi/testsuite/lib/wrapper.exp +45 -0
- data/ext/libffi/testsuite/libffi.call/call.exp +36 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
- data/ext/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
- data/ext/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
- data/ext/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
- data/ext/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
- data/ext/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
- data/ext/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
- data/ext/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
- data/ext/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
- data/ext/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
- data/ext/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
- data/ext/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
- data/ext/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
- data/ext/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
- data/ext/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
- data/ext/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
- data/ext/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
- data/ext/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
- data/ext/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
- data/ext/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
- data/ext/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
- data/ext/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
- data/ext/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
- data/ext/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
- data/ext/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
- data/ext/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
- data/ext/libffi/testsuite/libffi.call/cls_double.c +51 -0
- data/ext/libffi/testsuite/libffi.call/cls_float.c +51 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
- data/ext/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
- data/ext/libffi/testsuite/libffi.call/cls_schar.c +52 -0
- data/ext/libffi/testsuite/libffi.call/cls_sint.c +50 -0
- data/ext/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
- data/ext/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
- data/ext/libffi/testsuite/libffi.call/cls_uint.c +51 -0
- data/ext/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
- data/ext/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
- data/ext/libffi/testsuite/libffi.call/ffitest.h +86 -0
- data/ext/libffi/testsuite/libffi.call/float.c +59 -0
- data/ext/libffi/testsuite/libffi.call/float1.c +58 -0
- data/ext/libffi/testsuite/libffi.call/float2.c +57 -0
- data/ext/libffi/testsuite/libffi.call/float3.c +72 -0
- data/ext/libffi/testsuite/libffi.call/float4.c +62 -0
- data/ext/libffi/testsuite/libffi.call/many.c +69 -0
- data/ext/libffi/testsuite/libffi.call/many_win32.c +63 -0
- data/ext/libffi/testsuite/libffi.call/negint.c +53 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct.c +160 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
- data/ext/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
- data/ext/libffi/testsuite/libffi.call/problem1.c +98 -0
- data/ext/libffi/testsuite/libffi.call/promotion.c +59 -0
- data/ext/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
- data/ext/libffi/testsuite/libffi.call/return_dbl.c +35 -0
- data/ext/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
- data/ext/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
- data/ext/libffi/testsuite/libffi.call/return_fl.c +35 -0
- data/ext/libffi/testsuite/libffi.call/return_fl1.c +36 -0
- data/ext/libffi/testsuite/libffi.call/return_fl2.c +49 -0
- data/ext/libffi/testsuite/libffi.call/return_fl3.c +42 -0
- data/ext/libffi/testsuite/libffi.call/return_ldl.c +34 -0
- data/ext/libffi/testsuite/libffi.call/return_ll.c +41 -0
- data/ext/libffi/testsuite/libffi.call/return_ll1.c +42 -0
- data/ext/libffi/testsuite/libffi.call/return_sc.c +36 -0
- data/ext/libffi/testsuite/libffi.call/return_sl.c +38 -0
- data/ext/libffi/testsuite/libffi.call/return_uc.c +38 -0
- data/ext/libffi/testsuite/libffi.call/return_ul.c +38 -0
- data/ext/libffi/testsuite/libffi.call/strlen.c +44 -0
- data/ext/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
- data/ext/libffi/testsuite/libffi.call/struct1.c +65 -0
- data/ext/libffi/testsuite/libffi.call/struct2.c +67 -0
- data/ext/libffi/testsuite/libffi.call/struct3.c +59 -0
- data/ext/libffi/testsuite/libffi.call/struct4.c +63 -0
- data/ext/libffi/testsuite/libffi.call/struct5.c +65 -0
- data/ext/libffi/testsuite/libffi.call/struct6.c +64 -0
- data/ext/libffi/testsuite/libffi.call/struct7.c +74 -0
- data/ext/libffi/testsuite/libffi.call/struct8.c +80 -0
- data/ext/libffi/testsuite/libffi.call/struct9.c +67 -0
- data/ext/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
- data/ext/libffi/testsuite/libffi.special/special.exp +38 -0
- data/ext/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
- data/ext/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
- data/ext/libffi/texinfo.tex +7482 -0
- data/ext/rbffi.h +32 -0
- data/lib/ffi.rb +2 -0
- data/lib/ffi/buffer.rb +25 -0
- data/lib/ffi/callback.rb +10 -0
- data/lib/ffi/ffi.rb +259 -0
- data/lib/ffi/memorypointer.rb +169 -0
- data/lib/ffi/platform.rb +75 -0
- data/lib/ffi/struct.rb +263 -0
- data/nbproject/Makefile-Default.mk +54 -0
- data/nbproject/Makefile-impl.mk +123 -0
- data/nbproject/configurations.xml +169 -0
- data/nbproject/private/configurations.xml +22 -0
- data/nbproject/private/private.xml +7 -0
- data/nbproject/project.properties +0 -0
- data/nbproject/project.xml +11 -0
- data/samples/getlogin.rb +7 -0
- data/samples/getpid.rb +7 -0
- data/samples/gettimeofday.rb +13 -0
- data/samples/hello.rb +7 -0
- data/samples/qsort.rb +20 -0
- data/specs/buffer_spec.rb +141 -0
- data/specs/callback_spec.rb +31 -0
- data/specs/rbx/attach_function_spec.rb +26 -0
- data/specs/rbx/memory_pointer_spec.rb +108 -0
- data/specs/rbx/spec_helper.rb +1 -0
- data/specs/rbx/struct_spec.rb +13 -0
- data/specs/spec_helper.rb +2 -0
- metadata +359 -0
data/ext/rbffi.h
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
/*
|
2
|
+
* File: rbffi.h
|
3
|
+
* Author: wayne
|
4
|
+
*
|
5
|
+
* Created on August 27, 2008, 5:40 PM
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef _RBFFI_H
|
9
|
+
#define _RBFFI_H
|
10
|
+
|
11
|
+
#include <ruby.h>
|
12
|
+
|
13
|
+
#ifdef __cplusplus
|
14
|
+
extern "C" {
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define MAX_PARAMETERS (32)
|
18
|
+
|
19
|
+
extern void rb_FFI_AbstractMemory_Init();
|
20
|
+
extern void rb_FFI_MemoryPointer_Init();
|
21
|
+
extern void rb_FFI_Buffer_Init();
|
22
|
+
extern void rb_FFI_Callback_Init();
|
23
|
+
extern void rb_FFI_Invoker_Init();
|
24
|
+
extern VALUE rb_FFI_AbstractMemory_class;
|
25
|
+
|
26
|
+
|
27
|
+
#ifdef __cplusplus
|
28
|
+
}
|
29
|
+
#endif
|
30
|
+
|
31
|
+
#endif /* _RBFFI_H */
|
32
|
+
|
data/lib/ffi.rb
ADDED
data/lib/ffi/buffer.rb
ADDED
@@ -0,0 +1,25 @@
|
|
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/callback.rb
ADDED
data/lib/ffi/ffi.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
#
|
2
|
+
# Version: CPL 1.0/GPL 2.0/LGPL 2.1
|
3
|
+
#
|
4
|
+
# The contents of this file are subject to the Common Public
|
5
|
+
# License Version 1.0 (the "License"); you may not use this file
|
6
|
+
# except in compliance with the License. You may obtain a copy of
|
7
|
+
# the License at http://www.eclipse.org/legal/cpl-v10.html
|
8
|
+
#
|
9
|
+
# Software distributed under the License is distributed on an "AS
|
10
|
+
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
11
|
+
# implied. See the License for the specific language governing
|
12
|
+
# rights and limitations under the License.
|
13
|
+
#
|
14
|
+
# Copyright (C) 2008 JRuby project
|
15
|
+
#
|
16
|
+
# Alternatively, the contents of this file may be used under the terms of
|
17
|
+
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
18
|
+
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
19
|
+
# in which case the provisions of the GPL or the LGPL are applicable instead
|
20
|
+
# of those above. If you wish to allow use of your version of this file only
|
21
|
+
# under the terms of either the GPL or the LGPL, and not to allow others to
|
22
|
+
# use your version of this file under the terms of the CPL, indicate your
|
23
|
+
# decision by deleting the provisions above and replace them with the notice
|
24
|
+
# and other provisions required by the GPL or the LGPL. If you do not delete
|
25
|
+
# the provisions above, a recipient may use your version of this file under
|
26
|
+
# the terms of any one of the CPL, the GPL or the LGPL.
|
27
|
+
#
|
28
|
+
# Copyright (c) 2007, 2008 Evan Phoenix
|
29
|
+
# All rights reserved.
|
30
|
+
#
|
31
|
+
# Redistribution and use in source and binary forms, with or without
|
32
|
+
# modification, are permitted provided that the following conditions are met:
|
33
|
+
#
|
34
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
35
|
+
# list of conditions and the following disclaimer.
|
36
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
37
|
+
# this list of conditions and the following disclaimer in the documentation
|
38
|
+
# and/or other materials provided with the distribution.
|
39
|
+
# * Neither the name of the Evan Phoenix nor the names of its contributors
|
40
|
+
# may be used to endorse or promote products derived from this software
|
41
|
+
# without specific prior written permission.
|
42
|
+
#
|
43
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
44
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
45
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
46
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
47
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
48
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
49
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
50
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
51
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
52
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
53
|
+
|
54
|
+
module FFI
|
55
|
+
# Specialised error classes
|
56
|
+
class NativeError < LoadError; end
|
57
|
+
|
58
|
+
class TypeError < NativeError; end
|
59
|
+
|
60
|
+
class SignatureError < NativeError; end
|
61
|
+
|
62
|
+
class NotFoundError < NativeError
|
63
|
+
def initialize(function, library)
|
64
|
+
super("Function '#{function}' not found! (Looking in '#{library}' or this process)")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
require 'ffi/platform'
|
70
|
+
require 'ffi/memorypointer'
|
71
|
+
require 'ffi/buffer'
|
72
|
+
require 'ffi/struct'
|
73
|
+
require 'ffi/callback'
|
74
|
+
|
75
|
+
module FFI
|
76
|
+
TypeDefs = Hash.new
|
77
|
+
def self.add_typedef(current, add)
|
78
|
+
if current.kind_of? Integer
|
79
|
+
code = current
|
80
|
+
else
|
81
|
+
code = TypeDefs[current]
|
82
|
+
raise TypeError, "Unable to resolve type '#{current}'" unless code
|
83
|
+
end
|
84
|
+
|
85
|
+
TypeDefs[add] = code
|
86
|
+
end
|
87
|
+
def self.find_type(name)
|
88
|
+
code = TypeDefs[name]
|
89
|
+
code = name if !code && name.kind_of?(Integer)
|
90
|
+
code = name if !code && name.kind_of?(FFI::Callback)
|
91
|
+
raise TypeError, "Unable to resolve type '#{name}'" unless code
|
92
|
+
return code
|
93
|
+
end
|
94
|
+
|
95
|
+
# Converts a char
|
96
|
+
add_typedef(NativeType::INT8, :char)
|
97
|
+
|
98
|
+
# Converts an unsigned char
|
99
|
+
add_typedef(NativeType::UINT8, :uchar)
|
100
|
+
|
101
|
+
# Converts an 8 bit int
|
102
|
+
add_typedef(NativeType::INT8, :int8)
|
103
|
+
|
104
|
+
# Converts an unsigned char
|
105
|
+
add_typedef(NativeType::UINT8, :uint8)
|
106
|
+
|
107
|
+
# Converts a short
|
108
|
+
add_typedef(NativeType::INT16, :short)
|
109
|
+
|
110
|
+
# Converts an unsigned short
|
111
|
+
add_typedef(NativeType::UINT16, :ushort)
|
112
|
+
|
113
|
+
# Converts a 16bit int
|
114
|
+
add_typedef(NativeType::INT16, :int16)
|
115
|
+
|
116
|
+
# Converts an unsigned 16 bit int
|
117
|
+
add_typedef(NativeType::UINT16, :uint16)
|
118
|
+
|
119
|
+
# Converts an int
|
120
|
+
add_typedef(NativeType::INT32, :int)
|
121
|
+
|
122
|
+
# Converts an unsigned int
|
123
|
+
add_typedef(NativeType::UINT32, :uint)
|
124
|
+
|
125
|
+
# Converts a 32 bit int
|
126
|
+
add_typedef(NativeType::INT32, :int32)
|
127
|
+
|
128
|
+
# Converts an unsigned 16 bit int
|
129
|
+
add_typedef(NativeType::UINT32, :uint32)
|
130
|
+
|
131
|
+
# Converts a long
|
132
|
+
add_typedef(NativeType::LONG, :long)
|
133
|
+
|
134
|
+
# Converts an unsigned long
|
135
|
+
add_typedef(NativeType::ULONG, :ulong)
|
136
|
+
|
137
|
+
# Converts a 64 bit int
|
138
|
+
add_typedef(NativeType::INT64, :int64)
|
139
|
+
|
140
|
+
# Converts an unsigned 64 bit int
|
141
|
+
add_typedef(NativeType::UINT64, :uint64)
|
142
|
+
|
143
|
+
# Converts a long long
|
144
|
+
add_typedef(NativeType::INT64, :long_long)
|
145
|
+
|
146
|
+
# Converts an unsigned long long
|
147
|
+
add_typedef(NativeType::UINT64, :ulong_long)
|
148
|
+
|
149
|
+
# Converts a float
|
150
|
+
add_typedef(NativeType::FLOAT32, :float)
|
151
|
+
|
152
|
+
# Converts a double
|
153
|
+
add_typedef(NativeType::FLOAT64, :double)
|
154
|
+
|
155
|
+
# Converts a pointer to opaque data
|
156
|
+
add_typedef(NativeType::POINTER, :pointer)
|
157
|
+
|
158
|
+
# For when a function has no return value
|
159
|
+
add_typedef(NativeType::VOID, :void)
|
160
|
+
|
161
|
+
# Converts NUL-terminated C strings
|
162
|
+
add_typedef(NativeType::STRING, :string)
|
163
|
+
|
164
|
+
# Use for a C struct with a char [] embedded inside.
|
165
|
+
add_typedef(NativeType::CHAR_ARRAY, :char_array)
|
166
|
+
|
167
|
+
TypeSizes = {
|
168
|
+
1 => :char,
|
169
|
+
2 => :short,
|
170
|
+
4 => :int,
|
171
|
+
8 => :long_long,
|
172
|
+
}
|
173
|
+
|
174
|
+
SizeTypes = {
|
175
|
+
NativeType::INT8 => 1,
|
176
|
+
NativeType::UINT8 => 1,
|
177
|
+
NativeType::INT16 => 2,
|
178
|
+
NativeType::UINT16 => 2,
|
179
|
+
NativeType::INT32 => 4,
|
180
|
+
NativeType::UINT32 => 4,
|
181
|
+
NativeType::INT64 => 8,
|
182
|
+
NativeType::UINT64 => 8,
|
183
|
+
NativeType::FLOAT32 => 4,
|
184
|
+
NativeType::FLOAT64 => 8,
|
185
|
+
NativeType::LONG => FFI::Platform::LONG_SIZE / 8,
|
186
|
+
NativeType::ULONG => FFI::Platform::LONG_SIZE / 8,
|
187
|
+
NativeType::POINTER => FFI::Platform::ADDRESS_SIZE / 8,
|
188
|
+
}
|
189
|
+
def self.type_size(type)
|
190
|
+
if sz = SizeTypes[find_type(type)]
|
191
|
+
return sz
|
192
|
+
end
|
193
|
+
raise ArgumentError, "Unknown native type"
|
194
|
+
end
|
195
|
+
def self.create_invoker(lib, name, args, ret, convention = :default)
|
196
|
+
# Mangle the library name to reflect the native library naming conventions
|
197
|
+
if lib
|
198
|
+
lib = Platform::LIBPREFIX + lib unless lib =~ /^#{Platform::LIBPREFIX}/
|
199
|
+
lib += Platform::LIBSUFFIX unless lib =~ /#{Platform::LIBSUFFIX}/
|
200
|
+
end
|
201
|
+
# Current artificial limitation based on JRuby::FFI limit
|
202
|
+
raise SignatureError, 'FFI functions may take max 32 arguments!' if args.size > 32
|
203
|
+
|
204
|
+
invoker = FFI::Invoker.new(lib, name, args.map { |e| find_type(e) },
|
205
|
+
find_type(ret), convention.to_s)
|
206
|
+
raise NotFoundError.new(name, lib) unless invoker
|
207
|
+
return invoker
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
module FFI::Library
|
212
|
+
# TODO: Rubinius does *names here and saves the array. Multiple libs?
|
213
|
+
def ffi_lib(name)
|
214
|
+
@ffi_lib = name
|
215
|
+
end
|
216
|
+
def ffi_convention(convention)
|
217
|
+
@ffi_convention = convention
|
218
|
+
end
|
219
|
+
##
|
220
|
+
# Attach C function +name+ to this module.
|
221
|
+
#
|
222
|
+
# If you want to provide an alternate name for the module function, supply
|
223
|
+
# it after the +name+, otherwise the C function name will be used.#
|
224
|
+
#
|
225
|
+
# After the +name+, the C function argument types are provided as an Array.
|
226
|
+
#
|
227
|
+
# The C function return type is provided last.
|
228
|
+
|
229
|
+
def attach_function(mname, a3, a4, a5=nil)
|
230
|
+
cname, arg_types, ret_type = a5 ? [ a3, a4, a5 ] : [ mname.to_s, a3, a4 ]
|
231
|
+
lib = @ffi_lib
|
232
|
+
convention = @ffi_convention ? @ffi_convention : :default
|
233
|
+
# Convert :foo to the native type
|
234
|
+
arg_types.map! { |e|
|
235
|
+
begin
|
236
|
+
FFI.find_type(e)
|
237
|
+
rescue FFI::TypeError
|
238
|
+
@ffi_callbacks[e] || e
|
239
|
+
end
|
240
|
+
}
|
241
|
+
invoker = FFI.create_invoker lib, cname.to_s, arg_types, ret_type, convention
|
242
|
+
raise ArgumentError, "Unable to find function '#{cname}' to bind to #{self.name}.#{mname}" unless invoker
|
243
|
+
#
|
244
|
+
# Attach the invoker to this module as 'mname'.
|
245
|
+
#
|
246
|
+
self.module_eval <<-code
|
247
|
+
@ffi_invoker_#{mname} = invoker
|
248
|
+
def self.#{mname}(*args, &block)
|
249
|
+
@ffi_invoker_#{mname}.call(*args, &block)
|
250
|
+
end
|
251
|
+
code
|
252
|
+
invoker
|
253
|
+
end
|
254
|
+
def callback(name, args, ret)
|
255
|
+
@ffi_callbacks = Hash.new unless @ffi_callbacks
|
256
|
+
@ffi_callbacks[name] = FFI::Callback.new(FFI.find_type(ret), args.map { |e| FFI.find_type(e) })
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module FFI
|
2
|
+
class MemoryPointer
|
3
|
+
# call-seq:
|
4
|
+
# MemoryPointer.new(num) => MemoryPointer instance of <i>num</i> bytes
|
5
|
+
# MemoryPointer.new(sym) => MemoryPointer instance with number
|
6
|
+
# of bytes need by FFI type <i>sym</i>
|
7
|
+
# MemoryPointer.new(obj) => MemoryPointer instance with number
|
8
|
+
# of <i>obj.size</i> bytes
|
9
|
+
# MemoryPointer.new(sym, count) => MemoryPointer instance with number
|
10
|
+
# of bytes need by length-<i>count</i> array
|
11
|
+
# of FFI type <i>sym</i>
|
12
|
+
# MemoryPointer.new(obj, count) => MemoryPointer instance with number
|
13
|
+
# of bytes need by length-<i>count</i> array
|
14
|
+
# of <i>obj.size</i> bytes
|
15
|
+
# MemoryPointer.new(arg) { |p| ... }
|
16
|
+
#
|
17
|
+
# Both forms create a MemoryPointer instance. The number of bytes to
|
18
|
+
# allocate is either specified directly or by passing an FFI type, which
|
19
|
+
# specifies the number of bytes needed for that type.
|
20
|
+
#
|
21
|
+
# The form without a block returns the MemoryPointer instance. The form
|
22
|
+
# with a block yields the MemoryPointer instance and frees the memory
|
23
|
+
# when the block returns. The value returned is the value of the block.
|
24
|
+
|
25
|
+
def self.new(type, count=nil, clear=true)
|
26
|
+
size = if type.kind_of? Fixnum
|
27
|
+
type
|
28
|
+
elsif type.kind_of? Symbol
|
29
|
+
FFI.type_size(type)
|
30
|
+
else
|
31
|
+
type.size
|
32
|
+
end
|
33
|
+
ptr = self.__allocate(size, count, clear)
|
34
|
+
ptr.type_size = size
|
35
|
+
if block_given?
|
36
|
+
begin
|
37
|
+
value = yield ptr
|
38
|
+
ensure
|
39
|
+
ptr.free
|
40
|
+
end
|
41
|
+
value
|
42
|
+
else
|
43
|
+
ptr
|
44
|
+
end
|
45
|
+
end
|
46
|
+
def self.from_string(s)
|
47
|
+
ptr = self.new(s.length + 1, 1, false)
|
48
|
+
ptr.put_string(0, s)
|
49
|
+
ptr
|
50
|
+
end
|
51
|
+
# Indicates how many bytes the type that the pointer is cast as uses.
|
52
|
+
attr_accessor :type_size
|
53
|
+
|
54
|
+
# Access the MemoryPointer like a C array, accessing the +which+ number
|
55
|
+
# element in memory. The position of the element is calculate from
|
56
|
+
# +@type_size+ and +which+. A new MemoryPointer object is returned, which
|
57
|
+
# points to the address of the element.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
# ptr = MemoryPointer.new(:int, 20)
|
61
|
+
# new_ptr = ptr[9]
|
62
|
+
#
|
63
|
+
# c-equiv:
|
64
|
+
# int *ptr = (int*)malloc(sizeof(int) * 20);
|
65
|
+
# int *new_ptr;
|
66
|
+
# new_ptr = &ptr[9];
|
67
|
+
#
|
68
|
+
def [](which)
|
69
|
+
raise ArgumentError, "unknown type size" unless @type_size
|
70
|
+
self + (which * @type_size)
|
71
|
+
end
|
72
|
+
# Write +obj+ as a C int at the memory pointed to.
|
73
|
+
def write_int(obj)
|
74
|
+
put_int32(0, obj)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Read a C int from the memory pointed to.
|
78
|
+
def read_int
|
79
|
+
get_int32(0)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Write +obj+ as a C long at the memory pointed to.
|
83
|
+
def write_long(obj)
|
84
|
+
put_long(0, obj)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Read a C long from the memory pointed to.
|
88
|
+
def read_long
|
89
|
+
get_long(0)
|
90
|
+
end
|
91
|
+
# Write +obj+ as a C long long at the memory pointed to.
|
92
|
+
def write_long_long(obj)
|
93
|
+
put_int64(0, obj)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Read a C long long from the memory pointed to.
|
97
|
+
def read_long_long
|
98
|
+
get_int64(0)
|
99
|
+
end
|
100
|
+
def read_pointer
|
101
|
+
get_pointer(0)
|
102
|
+
end
|
103
|
+
def read_float
|
104
|
+
get_float32(0)
|
105
|
+
end
|
106
|
+
def write_float(obj)
|
107
|
+
put_float32(0, obj)
|
108
|
+
end
|
109
|
+
|
110
|
+
def read_string(len=nil)
|
111
|
+
if len
|
112
|
+
get_string(0, len)
|
113
|
+
else
|
114
|
+
get_string(0)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
def read_string_length(len)
|
118
|
+
get_string(0, len)
|
119
|
+
end
|
120
|
+
def read_string_to_null
|
121
|
+
get_string(0)
|
122
|
+
end
|
123
|
+
def write_string_length(str, len)
|
124
|
+
put_string(0, str, len)
|
125
|
+
end
|
126
|
+
def write_string(str, len=nil)
|
127
|
+
len = str.size unless len
|
128
|
+
# Write the string data without NUL termination
|
129
|
+
put_string(0, str, len)
|
130
|
+
end
|
131
|
+
def read_array_of_type(type, reader, length)
|
132
|
+
ary = []
|
133
|
+
size = FFI.type_size(type)
|
134
|
+
tmp = self
|
135
|
+
length.times {
|
136
|
+
ary << tmp.send(reader)
|
137
|
+
tmp += size
|
138
|
+
}
|
139
|
+
ary
|
140
|
+
end
|
141
|
+
|
142
|
+
def write_array_of_type(type, writer, ary)
|
143
|
+
size = FFI.type_size(type)
|
144
|
+
tmp = self
|
145
|
+
ary.each {|i|
|
146
|
+
tmp.send(writer, i)
|
147
|
+
tmp += size
|
148
|
+
}
|
149
|
+
self
|
150
|
+
end
|
151
|
+
def read_array_of_int(length)
|
152
|
+
get_array_of_int32(0, length)
|
153
|
+
end
|
154
|
+
|
155
|
+
def write_array_of_int(ary)
|
156
|
+
put_array_of_int32(0, ary)
|
157
|
+
end
|
158
|
+
|
159
|
+
def read_array_of_long(length)
|
160
|
+
get_array_of_long(0, length)
|
161
|
+
end
|
162
|
+
|
163
|
+
def write_array_of_long(ary)
|
164
|
+
put_array_of_long(0, ary)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
MemoryPointer = FFI::MemoryPointer
|