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.
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, parent = nil) ⇒ 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, parent = nil) ⇒ 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.
138 139 140 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 138 def initialize(pointer) initialize_vtbl(pointer) end |
Instance Attribute Details
#vtbl ⇒ Object (readonly)
Returns the value of attribute vtbl.
40 41 42 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 40 def vtbl @vtbl end |
#vtbl_parent ⇒ Object (readonly)
Returns the value of attribute vtbl_parent.
39 40 41 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 39 def vtbl_parent @vtbl_parent end |
Class Method Details
.com_interface(interface, parent = nil) ⇒ 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.
49 50 51 52 53 54 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 49 def com_interface(interface, parent=nil) # 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, parent) end |
.define_interface_function(name, return_type, spec = []) ⇒ Object
Defines a single function of a com interface
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 115 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.
107 108 109 110 111 112 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 107 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.
88 89 90 91 92 93 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 88 def define_interface_parent(parent) return if parent.nil? parent_klass = Object.module_eval("::VirtualBox::COM::FFI::#{::VirtualBox::COM::Util.version_const}::#{parent}::Vtbl") layout_args << [:superklass, parent_klass] end |
.define_interface_properties(interface) ⇒ Object
Defines all the properties on a com interface.
96 97 98 99 100 101 102 103 104 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 96 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, parent = nil) ⇒ Object
Creates the vtbl class associated with a given interface.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 67 def define_vtbl_for_interface(interface, parent=nil) # 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.
58 59 60 61 62 63 64 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 58 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.
130 131 132 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 130 def layout_args @_layout_args ||= [] end |
Instance Method Details
#initialize_vtbl(pointer) ⇒ Object
142 143 144 145 146 |
# File 'lib/virtualbox/com/ffi/interface.rb', line 142 def initialize_vtbl(pointer) klass = self.class @vtbl_parent = klass::VtblParent.new(pointer) @vtbl = klass::Vtbl.new(vtbl_parent[:vtbl]) end |