class WIN32OLE::Record
WIN32OLE::Record 对象表示 VT_RECORD OLE 变体。如果调用 OLE 方法的结果值是 VT_RECORD 类型,Win32OLE 将返回 WIN32OLE::Record 对象。
如果 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
那么,你可以从下面的 Ruby 脚本中检索 getBook 的返回值
require 'win32ole' obj = WIN32OLE.new('ComServer.ComClass') book = obj.getBook book.class # => WIN32OLE::Record book.title # => "The Ruby Book" book.cost # => 20
公共类方法
源代码
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 对象。第一个参数是结构体名称(String 或 Symbol)。第二个参数 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_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);
}
返回 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_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;
}
返回由 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_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);
}
返回由 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 Object 类具有 title 属性
那么从 Ruby 访问 ComObject 的 object_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_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);
}
设置由 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
那么设置 'title' 成员的值如下所示
srver = WIN32OLE.new('ComServer.ComClass') obj = WIN32OLE::Record.new('Book', server) obj.ole_instance_variable_set(:title, "The Ruby Book")
源代码
static VALUE
folerecord_to_h(VALUE self)
{
return rb_ivar_get(self, rb_intern("fields"));
}
返回表示 VT_RECORD 变量的 Ruby Hash 对象。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_typename(VALUE self)
{
return rb_ivar_get(self, rb_intern("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"