4 #This is a monkey patching follows for dlopen with RTLD_GLOBAL flag.
5 #With the original RTLD_LOCAL dynamic_cast did not work in ARC as expected because of the
6 #lack of rtti and returned NULL silently.
9 def ffi_global_lib(*names)
11 ffi_libs = names.map do |name|
12 if name == FFI::CURRENT_PROCESS
13 FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
15 libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
19 libnames.each do |libname|
21 lib = FFI::DynamicLibrary.open(libname, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
23 rescue Exception => ex
29 raise LoadError.new(errors.values.join('. '))
32 # return the found lib
43 class ArcClientCWrapper
45 class BaseStruct < FFI::Struct
51 result = val.read_string
56 def free_pointer(name)
58 if(val.is_a? FFI::Pointer)
63 def free_pointer_members
64 members.each do |member|
70 class SubmitResult < BaseStruct
71 layout :message, :pointer,\
75 class StatResult < BaseStruct
76 layout :message, :pointer,\
81 class GetResult < BaseStruct
82 layout :message, :pointer, \
90 THIS_DIR = File.dirname(__FILE__)
91 ffi_global_lib ['arc_client_c.so', 'arc_client_c.bundle'].map {|file| File.join THIS_DIR, file}
93 attach_function :initialize, [], :string
95 attach_function :arc_submit, [:int, :pointer], :pointer
96 attach_function :arc_stat, [:int, :pointer], :pointer
97 attach_function :arc_get, [:int, :pointer], :pointer
98 attach_function :arc_kill, [:int, :pointer], :int
100 def self.string_array_as_pointer(arr)
101 result = FFI::MemoryPointer.new(:pointer, arr.size)
102 result.write_array_of_pointer(arr.map {|item| FFI::MemoryPointer.from_string(item.to_s)})
105 def self.free_array_of_pointer(arr, length)
106 pointers = arr.read_array_of_pointer length