Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  
  package org.jruby.ext.ffi.jffi;
  
  import org.jruby.Ruby;
 
 @JRubyClass(name = "FFI::DynamicLibrary", parent = "Object")
 public class DynamicLibrary extends RubyObject {
     
     @JRubyConstant public static final int RTLD_LAZY   = 0x00001;
     @JRubyConstant public static final int RTLD_NOW    = 0x00002;
     @JRubyConstant public static final int RTLD_LOCAL  = 0x00004;
     @JRubyConstant public static final int RTLD_GLOBAL = 0x00008;
     
     private final Library library;
     private final String name;
     public static RubyClass createDynamicLibraryClass(Ruby runtimeRubyModule module) {
         RubyClass result = module.defineClassUnder("DynamicLibrary",
                 runtime.getObject(),
                 .);
 
         RubyClass symClass = result.defineClassUnder("Symbol",
                 module.getClass("Pointer"), .);
         symClass.defineAnnotatedMethods(Symbol.class);
         result.defineAnnotatedMethods(DynamicLibrary.class);
         result.defineAnnotatedConstants(DynamicLibrary.class);
 
         return result;
     }
     private static final int getNativeLibraryFlags(IRubyObject rbFlags) {
         int f = 0, flags = RubyNumeric.fix2int(rbFlags);
         f |= (flags & ) != 0 ? . : 0;
         f |= (flags & ) != 0 ? . : 0;
         f |= (flags & ) != 0 ? . : 0;
         f |= (flags & ) != 0 ? . : 0;
         return f;
     }
     public DynamicLibrary(Ruby runtimeRubyClass klassString nameLibrary library) {
         super(runtimeklass);
         this. = name;
         this. = library;
     }
     final Library getNativeLibrary() {
         return ;
     }
     @JRubyMethod(name = {  "open" }, meta = true)
     public static final  IRubyObject open(ThreadContext contextIRubyObject recvIRubyObject libraryNameIRubyObject libraryFlags) {
         final String libName = libraryName.isNil() ? null : libraryName.toString();
         try {
             Library library = Library.getCachedInstance(libNamegetNativeLibraryFlags(libraryFlags));
             if (library == null) {
                 throw new UnsatisfiedLinkError(Library.getLastError());
             }
             return new DynamicLibrary(context.runtime, (RubyClassrecv,
                     libNamelibrary);
         } catch (UnsatisfiedLinkError ex) {
             throw context.runtime.newLoadError(String.format("Could not open library '%s' : %s",
                     libName != null ? libName : "current process"ex.getMessage()));
         }
     }
     @JRubyMethod(name = {  "find_variable""find_symbol" })
     public IRubyObject findVariable(ThreadContext contextIRubyObject symbolName) {
         final String sym = symbolName.toString();
         final long address = .getSymbolAddress(sym);
         if (address == 0L) {
             return context.runtime.getNil();
         }
 
         return new Symbol(context.runtimethissymnew DataSymbolMemoryIO(context.runtimethisaddress));
     }
 
     @JRubyMethod(name = {  "find_function" })
     public IRubyObject findFunction(ThreadContext contextIRubyObject symbolName) {
         final String sym = symbolName.toString();
         final long address = .getSymbolAddress(sym);
         if (address == 0L) {
             return context.runtime.getNil();
         }
         return new Symbol(context.runtimethissym,
                 new TextSymbolMemoryIO(context.runtimethisaddress));
     }
     @JRubyMethod(name = "name")
     public IRubyObject name(ThreadContext context) {
         return  != null ? RubyString.newString(context.runtime) : context.runtime.getNil();
     }
    public static final class Symbol extends Pointer {
        private final DynamicLibrary library;
        private final String name;
        
        public Symbol(Ruby runtimeDynamicLibrary libraryString nameMemoryIO io) {
            super(runtimeruntime.getModule("FFI").getClass("DynamicLibrary").getClass("Symbol"),
                    io.);
            this. = library;
            this. = name;
        }
        @JRubyMethod(name = "library")
        public IRubyObject library(ThreadContext context) {
            return ;
        }
        
        @JRubyMethod(name = "inspect")
        public IRubyObject inspect(ThreadContext context) {
            return RubyString.newString(context.runtime,
                String.format("#<%s library=%s symbol=%s address=%#x>"
                    getMetaClass().getName(), .getAddress()));
        }
        @Override
        @JRubyMethod(name = "to_s", optional = 1)
        public IRubyObject to_s(ThreadContext contextIRubyObject[] args) {
            return RubyString.newString(context.runtime);
        }
        @Override
        public final String toString() {
            return ;
        }
        final String getName() {
            return ;
        }
    }

    
Small MemoryIO wrapper class to keep the library alive
    private static final class DataSymbolMemoryIO extends NativeMemoryIO {
        private final DynamicLibrary library;
        public DataSymbolMemoryIO(Ruby runtimeDynamicLibrary librarylong address) {
            super(runtimeaddress);
            this. = library;
        }
    }
    
    
Since the text area of a dynamic library is usually not readable nor writable, wrap the address in a MemoryIO instance that throws an exception on all accesses
    private static final class TextSymbolMemoryIO extends InvalidMemoryIO {
        private final DynamicLibrary library;
        public TextSymbolMemoryIO(Ruby runtimeDynamicLibrary librarylong address) {
            super(runtimetrueaddress"Library text region is inaccessible");
            this. = library;
        }
    }