In Files

  • win32ole/win32ole_record.c

WIN32OLE_RECORD

WIN32OLE_RECORD objects represents VT_RECORD OLE variant. Win32OLE returns WIN32OLE_RECORD object if the result value of invoking OLE methods.

If COM server in VB.NET ComServer project is the following:

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

then, you can retrieve getBook return value from the following Ruby script:

require 'win32ole'
obj = WIN32OLE.new('ComServer.ComClass')
book = obj.getBook
book.class # => WIN32OLE_RECORD
book.title # => "The Ruby Book"
book.cost  # => 20

Public Class Methods

new(typename, obj) → WIN32OLE_RECORD object click to toggle source

Returns WIN32OLE_RECORD object. The first argument is struct name (String or Symbol). The second parameter obj should be WIN32OLE object or WIN32OLE_TYPELIB object. If COM server in VB.NET ComServer project is the following:

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

then, you can create WIN32OLE_RECORD object is as following:

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_sym_to_s(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;
}
            

Public Instance Methods

WIN32OLE_RECORD#inspect → String click to toggle source

Returns the OLE struct name and member name and the value of member

If COM server in VB.NET ComServer project is the following:

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

then

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) click to toggle source

Returns value specified by the member name of VT_RECORD OLE variable. Or sets value specified by the member name of VT_RECORD OLE variable. If the member name is not correct, KeyError exception is raised.

If COM server in VB.NET ComServer project is the following:

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

Then getting/setting value from Ruby is as the following:

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_sym_to_s(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) click to toggle source

Returns value specified by the member name of VT_RECORD OLE object. If the member name is not correct, KeyError exception is raised. If you can’t access member variable of VT_RECORD OLE object directly, use this method.

If COM server in VB.NET ComServer project is the following:

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

and Ruby Object class has title attribute:

then accessing object_id of ComObject from Ruby is as the following:

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_sym_to_s(name);
    }
    return olerecord_ivar_get(self, sname);
}
            
WIN32OLE_RECORD#ole_instance_variable_set(name, val) click to toggle source

Sets value specified by the member name of VT_RECORD OLE object. If the member name is not correct, KeyError exception is raised. If you can’t set value of member of VT_RECORD OLE object directly, use this method.

If COM server in VB.NET ComServer project is the following:

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

then setting value of the `title’ member is as following:

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_sym_to_s(name);
    }
    return olerecord_ivar_set(self, sname, val);
}
            
WIN32OLE_RECORD#to_h #=> Ruby Hash object. click to toggle source

Returns Ruby Hash object which represents VT_RECORD variable. The keys of Hash object are member names of VT_RECORD OLE variable and the values of Hash object are values of VT_RECORD OLE variable.

If COM server in VB.NET ComServer project is the following:

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

then, the result of #to_h is the following:

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 #=> String object click to toggle source

Returns the type name of VT_RECORD OLE variable.

If COM server in VB.NET ComServer project is the following:

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

then, the result of #typename is the following:

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"));
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.