類別 WIN32OLE::Record

公開類別方法

new(typename, obj) → WIN32OLE_RECORD 物件 按一下以切換來源

傳回 WIN32OLE_RECORD 物件。第一個引數是結構名稱(字串符號)。第二個參數 obj 應該是 WIN32OLE 物件或 WIN32OLE_TYPELIB 物件。如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    Public Structure Book
        <MarshalAs(UnmanagedType.BStr)> _
        Public title As String
        Public cost As Integer
    End Structure
End Class

則您可以建立 WIN32OLE_RECORD 物件如下:

require 'win32ole'
obj = WIN32OLE.new('ComServer.ComClass')
book1 = WIN32OLE_RECORD.new('Book', obj) # => WIN32OLE_RECORD object
tlib = obj.ole_typelib
book2 = WIN32OLE_RECORD.new('Book', tlib) # => WIN32OLE_RECORD object
static VALUE
folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj) {
    HRESULT hr;
    ITypeLib *pTypeLib = NULL;
    IRecordInfo *pri = NULL;

    if (!RB_TYPE_P(typename, T_STRING) && !RB_TYPE_P(typename, T_SYMBOL)) {
        rb_raise(rb_eArgError, "1st argument should be String or Symbol");
    }
    if (RB_TYPE_P(typename, T_SYMBOL)) {
        typename = rb_sym2str(typename);
    }

    hr = S_OK;
    if(rb_obj_is_kind_of(oleobj, cWIN32OLE)) {
        hr = typelib_from_val(oleobj, &pTypeLib);
    } else if (rb_obj_is_kind_of(oleobj, cWIN32OLE_TYPELIB)) {
        pTypeLib = itypelib(oleobj);
        OLE_ADDREF(pTypeLib);
        if (pTypeLib) {
            hr = S_OK;
        } else {
            hr = E_FAIL;
        }
    } else {
        rb_raise(rb_eArgError, "2nd argument should be WIN32OLE object or WIN32OLE_TYPELIB object");
    }

    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "fail to query ITypeLib interface");
    }

    hr = recordinfo_from_itypelib(pTypeLib, typename, &pri);
    OLE_RELEASE(pTypeLib);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "fail to query IRecordInfo interface for `%s'", StringValuePtr(typename));
    }

    olerecord_set_ivar(self, pri, NULL);

    return self;
}

公開實例方法

WIN32OLE_RECORD#inspect → 字串 按一下以切換來源

傳回 OLE 結構名稱和成員名稱,以及成員的值

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    <MarshalAs(UnmanagedType.BStr)> _
    Public title As String
    Public cost As Integer
End Class

srver = WIN32OLE.new('ComServer.ComClass')
obj = WIN32OLE_RECORD.new('Book', server)
obj.inspect # => <WIN32OLE_RECORD(ComClass) {"title" => nil, "cost" => nil}>
static VALUE
folerecord_inspect(VALUE self)
{
    VALUE tname;
    VALUE field;
    tname = folerecord_typename(self);
    if (tname == Qnil) {
        tname = rb_inspect(tname);
    }
    field = rb_inspect(folerecord_to_h(self));
    return rb_sprintf("#<WIN32OLE_RECORD(%"PRIsVALUE") %"PRIsVALUE">",
                      tname,
                      field);
}
WIN32OLE_RECORD#method_missing(name) 按一下以切換來源

傳回 VT_RECORD OLE 變數的成員名稱所指定的數值。或設定 VT_RECORD OLE 變數的成員名稱所指定的數值。如果成員名稱不正確,會引發 KeyError 例外狀況。

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    Public Structure Book
        <MarshalAs(UnmanagedType.BStr)> _
        Public title As String
        Public cost As Integer
    End Structure
End Class

然後,從 Ruby 取得/設定數值如下:

obj = WIN32OLE.new('ComServer.ComClass')
book = WIN32OLE_RECORD.new('Book', obj)
book.title # => nil ( book.method_missing(:title) is invoked. )
book.title = "Ruby" # ( book.method_missing(:title=, "Ruby") is invoked. )
static VALUE
folerecord_method_missing(int argc, VALUE *argv, VALUE self)
{
    VALUE name;
    rb_check_arity(argc, 1, 2);
    name = rb_sym2str(argv[0]);

#if SIZEOF_SIZE_T > SIZEOF_LONG
    {
        size_t n = strlen(StringValueCStr(name));
        if (n >= LONG_MAX) {
            rb_raise(rb_eRuntimeError, "too long member name");
        }
    }
#endif

    if (argc == 1) {
        return olerecord_ivar_get(self, name);
    } else if (argc == 2) {
        return olerecord_ivar_set(self, name, argv[1]);
    }
    return Qnil;
}
WIN32OLE_RECORD#ole_instance_variable_get(name) 按一下以切換來源

傳回 VT_RECORD OLE 物件的成員名稱所指定的數值。如果成員名稱不正確,會引發 KeyError 例外狀況。如果您無法直接存取 VT_RECORD OLE 物件的成員變數,請使用此方法。

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    Public Structure ComObject
        Public object_id As Ineger
    End Structure
End Class

以及 Ruby 物件 類別具有標題屬性

則從 Ruby 存取 ComObject 的物件 ID 如下:

srver = WIN32OLE.new('ComServer.ComClass')
obj = WIN32OLE_RECORD.new('ComObject', server)
# obj.object_id returns Ruby Object#object_id
obj.ole_instance_variable_get(:object_id) # => nil
static VALUE
folerecord_ole_instance_variable_get(VALUE self, VALUE name)
{
    VALUE sname;
    if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
        rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    sname = name;
    if (RB_TYPE_P(name, T_SYMBOL)) {
        sname = rb_sym2str(name);
    }
    return olerecord_ivar_get(self, sname);
}
WIN32OLE_RECORD#ole_instance_variable_set(name, val) 按一下以切換來源

設定 VT_RECORD OLE 物件的成員名稱所指定的數值。如果成員名稱不正確,會引發 KeyError 例外狀況。如果您無法直接設定 VT_RECORD OLE 物件的成員數值,請使用此方法。

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    <MarshalAs(UnmanagedType.BStr)> _
    Public title As String
    Public cost As Integer
End Class

則設定「標題」成員的數值如下:

srver = WIN32OLE.new('ComServer.ComClass')
obj = WIN32OLE_RECORD.new('Book', server)
obj.ole_instance_variable_set(:title, "The Ruby Book")
static VALUE
folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val)
{
    VALUE sname;
    if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
        rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    sname = name;
    if (RB_TYPE_P(name, T_SYMBOL)) {
        sname = rb_sym2str(name);
    }
    return olerecord_ivar_set(self, sname, val);
}
WIN32OLE_RECORD#to_h #→ Ruby Hash 物件。 按一下以切換來源

傳回 Ruby Hash 物件,代表 VT_RECORD 變數。 Hash 物件的鍵是 VT_RECORD OLE 變數的成員名稱,而 Hash 物件的值是 VT_RECORD OLE 變數的值。

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    Public Structure Book
        <MarshalAs(UnmanagedType.BStr)> _
        Public title As String
        Public cost As Integer
    End Structure
    Public Function getBook() As Book
        Dim book As New Book
        book.title = "The Ruby Book"
        book.cost = 20
        Return book
    End Function
End Class

然後,WIN32OLE_RECORD#to_h 的結果如下所示

require 'win32ole'
obj = WIN32OLE.new('ComServer.ComClass')
book = obj.getBook
book.to_h # => {"title"=>"The Ruby Book", "cost"=>20}
static VALUE
folerecord_to_h(VALUE self)
{
    return rb_ivar_get(self, rb_intern("fields"));
}
WIN32OLE_RECORD#typename #→ 字串物件 按一下以切換來源

傳回 VT_RECORD OLE 變數的類型名稱。

如果 VB.NET ComServer 專案中的 COM 伺服器如下:

Imports System.Runtime.InteropServices
Public Class ComClass
    Public Structure Book
        <MarshalAs(UnmanagedType.BStr)> _
        Public title As String
        Public cost As Integer
    End Structure
    Public Function getBook() As Book
        Dim book As New Book
        book.title = "The Ruby Book"
        book.cost = 20
        Return book
    End Function
End Class

然後,WIN32OLE_RECORD#typename 的結果如下所示

require 'win32ole'
obj = WIN32OLE.new('ComServer.ComClass')
book = obj.getBook
book.typename # => "Book"
static VALUE
folerecord_typename(VALUE self)
{
    return rb_ivar_get(self, rb_intern("typename"));
}