Class: VirtualBox::COM::FFI::Interface
- Inherits:
-
Object
- Object
- VirtualBox::COM::FFI::Interface
- Extended by:
- FFI::Library
- Defined in:
- lib/virtualbox/com/ffi/interface.rb
Overview
Represents a VirtualBox XPCOM C interface, which is a C struct which emulates an object (a struct with function pointers and getters/setters). This class does **a lot** of magic which pretty much represents everything wrong about ruby programmers, but keep in mind it is well tested and well commented, and the meta-programming was done out of a need to keep things DRY between Windows and Unix operating systems.
Constant Summary collapse
- NSRESULT_TYPE =
FFI specific types
:uint
Instance Attribute Summary collapse
-
#vtbl ⇒ Object
readonly
Returns the value of attribute vtbl.
-
#vtbl_parent ⇒ Object
readonly
Returns the value of attribute vtbl_parent.
Class Method Summary collapse
-
.com_interface(interface) ⇒ Object
Sets up the args to the FFI::Struct ‘layout` method.
-
.define_interface_function(name, return_type, spec = []) ⇒ Object
Defines a single function of a com interface.
-
.define_interface_functions(interface) ⇒ Object
Defines all the functions on a com interface.
-
.define_interface_parent(parent) ⇒ Object
Defines the parent item of the layout.
-
.define_interface_properties(interface) ⇒ Object
Defines all the properties on a com interface.
-
.define_vtbl_for_interface(interface) ⇒ Object
Creates the vtbl class associated with a given interface.
-
.define_vtbl_parent_for_interface(interface) ⇒ Object
Creates the parent of the vtbl class associated with a given interface.
-
.layout_args ⇒ Array
Returns an array of the layout args to send to ‘layout` eventually.
Instance Method Summary collapse
-
#initialize(pointer) ⇒ Interface
constructor
Initializes the interface to the FFI struct with the given pointer.
- #initialize_vtbl(pointer) ⇒ Object
Constructor Details
#initialize(pointer) ⇒ Interface
Initializes the interface to the FFI struct with the given pointer. The pointer is used to initialize the VtblParent which is used to initialize the Vtbl itself.
121 122 123 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 121 def initialize(pointer) initialize_vtbl(pointer) end |
Instance Attribute Details
#vtbl ⇒ Object (readonly)
Returns the value of attribute vtbl.
20 21 22 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 20 def vtbl @vtbl end |
#vtbl_parent ⇒ Object (readonly)
Returns the value of attribute vtbl_parent.
19 20 21 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 19 def vtbl_parent @vtbl_parent end |
Class Method Details
.com_interface(interface) ⇒ Object
Sets up the args to the FFI::Struct ‘layout` method. This method defines all the callbacks necessary for working with FFI and also sets up any layout args to send in. The way the XPCOM C structs are setup, the properties are first, in `GetFoo` and `SetFoo` format. And the functions are next. They are put into the struct in the order defined in the AbstractInterface.
29 30 31 32 33 34 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 29 def com_interface(interface) # Create the parent class and vtbl class interface = ::VirtualBox::COM::Util.versioned_interface(interface) define_vtbl_parent_for_interface(interface) define_vtbl_for_interface(interface) end |
.define_interface_function(name, return_type, spec = []) ⇒ Object
Defines a single function of a com interface
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 98 def define_interface_function(name, return_type, spec=[]) # Append the return type to the spec as an out parameter (this is how # the C API handles it) spec << [:out, return_type] unless return_type.nil? # Define the "callback" type for the FFI module callback(name, Util.spec_to_ffi(spec), NSRESULT_TYPE) # Add to the layout args layout_args << [name, name] end |
.define_interface_functions(interface) ⇒ Object
Defines all the functions on a com interface.
90 91 92 93 94 95 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 90 def define_interface_functions(interface) interface.functions.each do |name, opts| # Define the function define_interface_function(name, opts[:value_type], opts[:spec].dup) end end |
.define_interface_parent(parent) ⇒ Object
Defines the parent item of the layout. Since the VirtualBox XPCOM C library emulates an object-oriented environment using structs, the parent instance is pointed to by the first member of the struct. This method sets up that member.
71 72 73 74 75 76 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 71 def define_interface_parent(parent) return if parent.nil? parent_klass = Util.versioned_interface(parent).const_get("Vtbl") layout_args << [:superklass, parent_klass] end |
.define_interface_properties(interface) ⇒ Object
Defines all the properties on a com interface.
79 80 81 82 83 84 85 86 87 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 79 def define_interface_properties(interface) interface.properties.each do |name, opts| # Define the getter define_interface_function("get_#{name}".to_sym, opts[:value_type]) # Define the setter unless the property is readonly define_interface_function("set_#{name}".to_sym, nil, [opts[:value_type]]) unless opts[:opts] && opts[:opts][:readonly] end end |
.define_vtbl_for_interface(interface) ⇒ Object
Creates the vtbl class associated with a given interface.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 47 def define_vtbl_for_interface(interface) # Get the parent for the interface parent = interface.get_parent # Define the properties, then the functions, since thats the order # the FFI structs are in layout_args.clear define_interface_parent(parent) define_interface_properties(interface) define_interface_functions(interface) # Finally create the classes (the struct and the structs vtbl) @vtbl_klass = Class.new(::FFI::Struct) # Set the constant within this class const_set("Vtbl", @vtbl_klass).layout(*layout_args.flatten) end |
.define_vtbl_parent_for_interface(interface) ⇒ Object
Creates the parent of the vtbl class associated with a given interface.
38 39 40 41 42 43 44 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 38 def define_vtbl_parent_for_interface(interface) @vtbl_parent_klass = Class.new(::FFI::Struct) @vtbl_parent_klass.layout(:vtbl, :pointer) # Set the constant const_set("VtblParent", @vtbl_parent_klass) end |
.layout_args ⇒ Array
Returns an array of the layout args to send to ‘layout` eventually.
113 114 115 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 113 def layout_args @_layout_args ||= [] end |
Instance Method Details
#initialize_vtbl(pointer) ⇒ Object
125 126 127 128 129 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 125 def initialize_vtbl(pointer) klass = self.class @vtbl_parent = klass::VtblParent.new(pointer) @vtbl = klass::Vtbl.new(vtbl_parent[:vtbl]) end |