module WindowsCOM::COMCallback
Public Class Methods
[](iface)
click to toggle source
# File lib/windows_com/common.rb, line 241 def self.[](iface) Class.new(iface) { def initialize @vtbl = self.class::Vtbl.new @vtbl.members.each { |name| params, ret = @vtbl.class::Spec[name] ffi_params = [:pointer, *params] # prepend *this* ptr to FFI func signature @vtbl[name] = instance_variable_set("@__ffi_func__#{name}", FFI::Function.new(ret, ffi_params, convention: :stdcall) { |*args| args.shift # remove *this* ptr for Ruby meth call STDERR.puts [:rb_call, self.class, name, args].inspect if WINDOWS_COM_TRACE_CALL_ARGS __send__(name, *args) } ) } @vptr = WindowsCOM::COMVptr_.new @vptr[:lpVtbl] = @vtbl @refc = 0 AddRef() end attr_reader :refc def QueryInterface(iid, ppv) unless self.class::IID == iid || WindowsCOM::IUnknown::IID == iid STDERR.puts "#{self}.#{__method__} called with unsupported interface id (IID: #{iid})" if $DEBUG ppv.write_pointer(0) return WindowsCOM::E_NOINTERFACE end ppv.write_pointer(@vptr) AddRef() WindowsCOM::S_OK end def AddRef @refc += 1 STDERR.puts "#{self}.#{__method__} (@refc: #{@refc})" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT @refc end def Release @refc -= 1 STDERR.puts "#{self}.#{__method__} (@refc: #{@refc})" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT if @refc == 0 @vtbl.pointer.free @vptr.pointer.free STDERR.puts "#{self}.@#{@vtbl} freed\n#{self}.@#{@vptr} freed" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT end @refc end (self::Vtbl.members - WindowsCOM::IUnknown::Vtbl.members).each { |name| define_method(name) { |*args| WindowsCOM::E_NOTIMPL } } } end
new()
click to toggle source
# File lib/windows_com/common.rb, line 243 def initialize @vtbl = self.class::Vtbl.new @vtbl.members.each { |name| params, ret = @vtbl.class::Spec[name] ffi_params = [:pointer, *params] # prepend *this* ptr to FFI func signature @vtbl[name] = instance_variable_set("@__ffi_func__#{name}", FFI::Function.new(ret, ffi_params, convention: :stdcall) { |*args| args.shift # remove *this* ptr for Ruby meth call STDERR.puts [:rb_call, self.class, name, args].inspect if WINDOWS_COM_TRACE_CALL_ARGS __send__(name, *args) } ) } @vptr = WindowsCOM::COMVptr_.new @vptr[:lpVtbl] = @vtbl @refc = 0 AddRef() end
Public Instance Methods
AddRef()
click to toggle source
# File lib/windows_com/common.rb, line 283 def AddRef @refc += 1 STDERR.puts "#{self}.#{__method__} (@refc: #{@refc})" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT @refc end
QueryInterface(iid, ppv)
click to toggle source
# File lib/windows_com/common.rb, line 270 def QueryInterface(iid, ppv) unless self.class::IID == iid || WindowsCOM::IUnknown::IID == iid STDERR.puts "#{self}.#{__method__} called with unsupported interface id (IID: #{iid})" if $DEBUG ppv.write_pointer(0) return WindowsCOM::E_NOINTERFACE end ppv.write_pointer(@vptr) AddRef() WindowsCOM::S_OK end
Release()
click to toggle source
# File lib/windows_com/common.rb, line 292 def Release @refc -= 1 STDERR.puts "#{self}.#{__method__} (@refc: #{@refc})" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT if @refc == 0 @vtbl.pointer.free @vptr.pointer.free STDERR.puts "#{self}.@#{@vtbl} freed\n#{self}.@#{@vptr} freed" if $DEBUG || WINDOWS_COM_TRACE_CALLBACK_REFCOUNT end @refc end