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