summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/win32ole/win32ole.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index 4ffd32fb70..9f1ae2ea33 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -143,7 +143,7 @@ const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00,
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
-#define WIN32OLE_VERSION "1.6.4"
+#define WIN32OLE_VERSION "1.6.5"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -610,6 +610,8 @@ static VALUE folerecord_s_allocate(VALUE klass);
static VALUE folerecord_initialize(VALUE self, VALUE args);
static VALUE folerecord_to_h(VALUE self);
static VALUE folerecord_typename(VALUE self);
+static VALUE olerecord_ivar_get(VALUE self, VALUE name);
+static VALUE olerecord_ivar_set(VALUE self, VALUE name, VALUE val);
static VALUE folerecord_method_missing(int argc, VALUE *argv, VALUE self);
static void init_enc2cp(void);
static void free_enc2cp(void);
@@ -9491,39 +9493,70 @@ folerecord_typename(VALUE self)
return rb_ivar_get(self, rb_intern("typename"));
}
+static VALUE
+olerecord_ivar_get(VALUE self, VALUE name)
+{
+ VALUE fields;
+ fields = rb_ivar_get(self, rb_intern("fields"));
+ return rb_hash_fetch(fields, name);
+}
+
+static VALUE
+olerecord_ivar_set(VALUE self, VALUE name, VALUE val)
+{
+ long len;
+ char *p;
+ VALUE ch;
+ VALUE fields;
+ len = RSTRING_LEN(name);
+ ch = rb_str_subseq(name, len-1, 1);
+ p = RSTRING_PTR(ch);
+ if (*p == '=') {
+ fields = rb_ivar_get(self, rb_intern("fields"));
+ name = rb_str_subseq(name, 0, len-1);
+ rb_hash_fetch(fields, name);
+ return rb_hash_aset(fields, name, val);
+ } else {
+ rb_raise(rb_eRuntimeError, "unknown member name:`%s`", RSTRING_PTR(name));
+ }
+}
+
/*
* call-seq:
* WIN32OLE_RECORD#method_missing(name)
*
* 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)
{
- long len = 0;
VALUE name;
- VALUE ch;
- char *p;
- VALUE fields;
-
rb_check_arity(argc, 1, 2);
- fields = rb_ivar_get(self, rb_intern("fields"));
+ name = rb_sym_to_s(argv[0]);
if (argc == 1) {
- name = rb_sym_to_s(argv[0]);
- return rb_hash_fetch(fields, name);
+ return olerecord_ivar_get(self, name);
} else if (argc == 2) {
- name = rb_sym_to_s(argv[0]);
- len = RSTRING_LEN(name);
- ch = rb_str_subseq(name, len-1, 1);
- p = RSTRING_PTR(ch);
- if (*p == '=') {
- name = rb_str_subseq(name, 0, len-1);
- rb_hash_fetch(fields, name);
- return rb_hash_aset(fields, name, argv[1]);
- } else {
- rb_raise(rb_eRuntimeError, "unknown member name:`%s`", RSTRING_PTR(name));
- }
+ return olerecord_ivar_set(self, name, argv[1]);
}
return Qnil;
}