module Unknownr::Windows::COM::Callback
Public Class Methods
[](iface)
click to toggle source
# File lib/unknownr.rb, line 216 def self.[](iface) Class.new(iface) { send(:include, Helpers) def initialize(opts = {}) @vtbl, @refc = self.class::VTBL.new, 1 @vtbl.members.each { |name| @vtbl[name] = instance_variable_set("@fn#{name}", FFI::Function.new(*@vtbl.class::SPEC[name].reverse, convention: :stdcall) { |*args| send(name, *args[1..-1]) } ) } self[:lpVtbl] = @vtbl begin yield self ensure Release() end if block_given? end attr_reader :vtbl, :refc def QueryInterface(riid, ppv) if [IUnknown::IID, self.class::IID].any? { |iid| Windows.memcmp(riid, iid, iid.size) == 0 } ppv.write_pointer(self) else ppv.write_pointer(0); return E_NOINTERFACE end AddRef(); S_OK end def AddRef @refc += 1 end def Release @refc -= 1 end (self::VTBL.members - IUnknown::VTBL.members).each { |name| define_method(name) { |*args| E_NOTIMPL } } } end
new(opts = {}) { |self| ... }
click to toggle source
# File lib/unknownr.rb, line 220 def initialize(opts = {}) @vtbl, @refc = self.class::VTBL.new, 1 @vtbl.members.each { |name| @vtbl[name] = instance_variable_set("@fn#{name}", FFI::Function.new(*@vtbl.class::SPEC[name].reverse, convention: :stdcall) { |*args| send(name, *args[1..-1]) } ) } self[:lpVtbl] = @vtbl begin yield self ensure Release() end if block_given? end
Public Instance Methods
AddRef()
click to toggle source
# File lib/unknownr.rb, line 252 def AddRef @refc += 1 end
QueryInterface(riid, ppv)
click to toggle source
# File lib/unknownr.rb, line 242 def QueryInterface(riid, ppv) if [IUnknown::IID, self.class::IID].any? { |iid| Windows.memcmp(riid, iid, iid.size) == 0 } ppv.write_pointer(self) else ppv.write_pointer(0); return E_NOINTERFACE end AddRef(); S_OK end
Release()
click to toggle source
# File lib/unknownr.rb, line 256 def Release @refc -= 1 end