Ruby  2.5.0dev(2017-10-22revision60238)
win32ole_record.c
Go to the documentation of this file.
1 #include "win32ole.h"
2 
3 struct olerecorddata {
4  IRecordInfo *pri;
5  void *pdata;
6 };
7 
8 static HRESULT recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri);
9 static int hash2olerec(VALUE key, VALUE val, VALUE rec);
10 static void olerecord_free(void *pvar);
11 static size_t olerecord_size(const void *ptr);
12 static VALUE folerecord_s_allocate(VALUE klass);
13 static VALUE folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj);
14 static VALUE folerecord_to_h(VALUE self);
15 static VALUE folerecord_typename(VALUE self);
16 static VALUE olerecord_ivar_get(VALUE self, VALUE name);
17 static VALUE olerecord_ivar_set(VALUE self, VALUE name, VALUE val);
18 static VALUE folerecord_method_missing(int argc, VALUE *argv, VALUE self);
19 static VALUE folerecord_ole_instance_variable_get(VALUE self, VALUE name);
20 static VALUE folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val);
21 static VALUE folerecord_inspect(VALUE self);
22 
23 static const rb_data_type_t olerecord_datatype = {
24  "win32ole_record",
25  {NULL, olerecord_free, olerecord_size,},
27 };
28 
29 static HRESULT
30 recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri)
31 {
32 
33  unsigned int count;
34  unsigned int i;
35  ITypeInfo *pTypeInfo;
36  HRESULT hr = OLE_E_LAST;
37  BSTR bstr;
38 
39  count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
40  for (i = 0; i < count; i++) {
41  hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
42  &bstr, NULL, NULL, NULL);
43  if (FAILED(hr))
44  continue;
45 
46  hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
47  if (FAILED(hr))
48  continue;
49 
50  if (rb_str_cmp(WC2VSTR(bstr), name) == 0) {
51  hr = GetRecordInfoFromTypeInfo(pTypeInfo, ppri);
52  OLE_RELEASE(pTypeInfo);
53  return hr;
54  }
55  OLE_RELEASE(pTypeInfo);
56  }
57  hr = OLE_E_LAST;
58  return hr;
59 }
60 
61 static int
62 hash2olerec(VALUE key, VALUE val, VALUE rec)
63 {
64  VARIANT var;
65  OLECHAR *pbuf;
66  struct olerecorddata *prec;
67  IRecordInfo *pri;
68  HRESULT hr;
69 
70  if (val != Qnil) {
71  TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec);
72  pri = prec->pri;
73  VariantInit(&var);
74  ole_val2variant(val, &var);
75  pbuf = ole_vstr2wc(key);
76  hr = pri->lpVtbl->PutField(pri, INVOKE_PROPERTYPUT, prec->pdata, pbuf, &var);
77  SysFreeString(pbuf);
78  VariantClear(&var);
79  if (FAILED(hr)) {
80  ole_raise(hr, eWIN32OLERuntimeError, "failed to putfield of `%s`", StringValuePtr(key));
81  }
82  }
83  return ST_CONTINUE;
84 }
85 
86 void
87 ole_rec2variant(VALUE rec, VARIANT *var)
88 {
89  struct olerecorddata *prec;
90  ULONG size = 0;
91  IRecordInfo *pri;
92  HRESULT hr;
93  VALUE fields;
94  TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec);
95  pri = prec->pri;
96  if (pri) {
97  hr = pri->lpVtbl->GetSize(pri, &size);
98  if (FAILED(hr)) {
99  ole_raise(hr, eWIN32OLERuntimeError, "failed to get size for allocation of VT_RECORD object");
100  }
101  if (prec->pdata) {
102  free(prec->pdata);
103  }
104  prec->pdata = ALLOC_N(char, size);
105  if (!prec->pdata) {
106  rb_raise(rb_eRuntimeError, "failed to memory allocation of %lu bytes", (unsigned long)size);
107  }
108  hr = pri->lpVtbl->RecordInit(pri, prec->pdata);
109  if (FAILED(hr)) {
110  ole_raise(hr, eWIN32OLERuntimeError, "failed to initialize VT_RECORD object");
111  }
112  fields = folerecord_to_h(rec);
113  rb_hash_foreach(fields, hash2olerec, rec);
114  V_RECORDINFO(var) = pri;
115  V_RECORD(var) = prec->pdata;
116  V_VT(var) = VT_RECORD;
117  } else {
118  rb_raise(eWIN32OLERuntimeError, "failed to retrieve IRecordInfo interface");
119  }
120 }
121 
122 void
123 olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
124 {
125  HRESULT hr;
126  BSTR bstr;
127  BSTR *bstrs;
128  ULONG count = 0;
129  ULONG i;
130  VALUE fields;
131  VALUE val;
132  VARIANT var;
133  void *pdata = NULL;
134  struct olerecorddata *pvar;
135 
136  TypedData_Get_Struct(obj, struct olerecorddata, &olerecord_datatype, pvar);
137  OLE_ADDREF(pri);
138  OLE_RELEASE(pvar->pri);
139  pvar->pri = pri;
140 
141  hr = pri->lpVtbl->GetName(pri, &bstr);
142  if (SUCCEEDED(hr)) {
143  rb_ivar_set(obj, rb_intern("typename"), WC2VSTR(bstr));
144  }
145 
146  hr = pri->lpVtbl->GetFieldNames(pri, &count, NULL);
147  if (FAILED(hr) || count == 0)
148  return;
149  bstrs = ALLOCA_N(BSTR, count);
150  hr = pri->lpVtbl->GetFieldNames(pri, &count, bstrs);
151  if (FAILED(hr)) {
152  return;
153  }
154 
155  fields = rb_hash_new();
156  rb_ivar_set(obj, rb_intern("fields"), fields);
157  for (i = 0; i < count; i++) {
158  pdata = NULL;
159  VariantInit(&var);
160  val = Qnil;
161  if (prec) {
162  hr = pri->lpVtbl->GetFieldNoCopy(pri, prec, bstrs[i], &var, &pdata);
163  if (SUCCEEDED(hr)) {
164  val = ole_variant2val(&var);
165  }
166  }
167  rb_hash_aset(fields, WC2VSTR(bstrs[i]), val);
168  }
169 }
170 
171 VALUE
172 create_win32ole_record(IRecordInfo *pri, void *prec)
173 {
174  VALUE obj = folerecord_s_allocate(cWIN32OLE_RECORD);
175  olerecord_set_ivar(obj, pri, prec);
176  return obj;
177 }
178 
179 /*
180  * Document-class: WIN32OLE_RECORD
181  *
182  * <code>WIN32OLE_RECORD</code> objects represents VT_RECORD OLE variant.
183  * Win32OLE returns WIN32OLE_RECORD object if the result value of invoking
184  * OLE methods.
185  *
186  * If COM server in VB.NET ComServer project is the following:
187  *
188  * Imports System.Runtime.InteropServices
189  * Public Class ComClass
190  * Public Structure Book
191  * <MarshalAs(UnmanagedType.BStr)> _
192  * Public title As String
193  * Public cost As Integer
194  * End Structure
195  * Public Function getBook() As Book
196  * Dim book As New Book
197  * book.title = "The Ruby Book"
198  * book.cost = 20
199  * Return book
200  * End Function
201  * End Class
202  *
203  * then, you can retrieve getBook return value from the following
204  * Ruby script:
205  *
206  * require 'win32ole'
207  * obj = WIN32OLE.new('ComServer.ComClass')
208  * book = obj.getBook
209  * book.class # => WIN32OLE_RECORD
210  * book.title # => "The Ruby Book"
211  * book.cost # => 20
212  *
213  */
214 
215 static void
216 olerecord_free(void *ptr) {
217  struct olerecorddata *pvar = ptr;
218  OLE_FREE(pvar->pri);
219  if (pvar->pdata) {
220  free(pvar->pdata);
221  }
222  free(pvar);
223 }
224 
225 static size_t
226 olerecord_size(const void *ptr)
227 {
228  const struct olerecorddata *pvar = ptr;
229  size_t s = 0;
230  ULONG size = 0;
231  HRESULT hr;
232  if (ptr) {
233  s += sizeof(struct olerecorddata);
234  if (pvar->pri) {
235  hr = pvar->pri->lpVtbl->GetSize(pvar->pri, &size);
236  if (SUCCEEDED(hr)) {
237  s += size;
238  }
239  }
240  }
241  return s;
242 }
243 
244 static VALUE
245 folerecord_s_allocate(VALUE klass) {
246  VALUE obj = Qnil;
247  struct olerecorddata *pvar;
248  obj = TypedData_Make_Struct(klass, struct olerecorddata, &olerecord_datatype, pvar);
249  pvar->pri = NULL;
250  pvar->pdata = NULL;
251  return obj;
252 }
253 
254 /*
255  * call-seq:
256  * WIN32OLE_RECORD.new(typename, obj) -> WIN32OLE_RECORD object
257  *
258  * Returns WIN32OLE_RECORD object. The first argument is struct name (String
259  * or Symbol).
260  * The second parameter obj should be WIN32OLE object or WIN32OLE_TYPELIB object.
261  * If COM server in VB.NET ComServer project is the following:
262  *
263  * Imports System.Runtime.InteropServices
264  * Public Class ComClass
265  * Public Structure Book
266  * <MarshalAs(UnmanagedType.BStr)> _
267  * Public title As String
268  * Public cost As Integer
269  * End Structure
270  * End Class
271  *
272  * then, you can create WIN32OLE_RECORD object is as following:
273  *
274  * require 'win32ole'
275  * obj = WIN32OLE.new('ComServer.ComClass')
276  * book1 = WIN32OLE_RECORD.new('Book', obj) # => WIN32OLE_RECORD object
277  * tlib = obj.ole_typelib
278  * book2 = WIN32OLE_RECORD.new('Book', tlib) # => WIN32OLE_RECORD object
279  *
280  */
281 static VALUE
282 folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj) {
283  HRESULT hr;
284  ITypeLib *pTypeLib = NULL;
285  IRecordInfo *pri = NULL;
286 
287  if (!RB_TYPE_P(typename, T_STRING) && !RB_TYPE_P(typename, T_SYMBOL)) {
288  rb_raise(rb_eArgError, "1st argument should be String or Symbol");
289  }
290  if (RB_TYPE_P(typename, T_SYMBOL)) {
291  typename = rb_sym2str(typename);
292  }
293 
294  hr = S_OK;
295  if(rb_obj_is_kind_of(oleobj, cWIN32OLE)) {
296  hr = typelib_from_val(oleobj, &pTypeLib);
297  } else if (rb_obj_is_kind_of(oleobj, cWIN32OLE_TYPELIB)) {
298  pTypeLib = itypelib(oleobj);
299  OLE_ADDREF(pTypeLib);
300  if (pTypeLib) {
301  hr = S_OK;
302  } else {
303  hr = E_FAIL;
304  }
305  } else {
306  rb_raise(rb_eArgError, "2nd argument should be WIN32OLE object or WIN32OLE_TYPELIB object");
307  }
308 
309  if (FAILED(hr)) {
310  ole_raise(hr, eWIN32OLERuntimeError, "fail to query ITypeLib interface");
311  }
312 
313  hr = recordinfo_from_itypelib(pTypeLib, typename, &pri);
314  OLE_RELEASE(pTypeLib);
315  if (FAILED(hr)) {
316  ole_raise(hr, eWIN32OLERuntimeError, "fail to query IRecordInfo interface for `%s'", StringValuePtr(typename));
317  }
318 
319  olerecord_set_ivar(self, pri, NULL);
320 
321  return self;
322 }
323 
324 /*
325  * call-seq:
326  * WIN32OLE_RECORD#to_h #=> Ruby Hash object.
327  *
328  * Returns Ruby Hash object which represents VT_RECORD variable.
329  * The keys of Hash object are member names of VT_RECORD OLE variable and
330  * the values of Hash object are values of VT_RECORD OLE variable.
331  *
332  * If COM server in VB.NET ComServer project is the following:
333  *
334  * Imports System.Runtime.InteropServices
335  * Public Class ComClass
336  * Public Structure Book
337  * <MarshalAs(UnmanagedType.BStr)> _
338  * Public title As String
339  * Public cost As Integer
340  * End Structure
341  * Public Function getBook() As Book
342  * Dim book As New Book
343  * book.title = "The Ruby Book"
344  * book.cost = 20
345  * Return book
346  * End Function
347  * End Class
348  *
349  * then, the result of WIN32OLE_RECORD#to_h is the following:
350  *
351  * require 'win32ole'
352  * obj = WIN32OLE.new('ComServer.ComClass')
353  * book = obj.getBook
354  * book.to_h # => {"title"=>"The Ruby Book", "cost"=>20}
355  *
356  */
357 static VALUE
358 folerecord_to_h(VALUE self)
359 {
360  return rb_ivar_get(self, rb_intern("fields"));
361 }
362 
363 /*
364  * call-seq:
365  * WIN32OLE_RECORD#typename #=> String object
366  *
367  * Returns the type name of VT_RECORD OLE variable.
368  *
369  * If COM server in VB.NET ComServer project is the following:
370  *
371  * Imports System.Runtime.InteropServices
372  * Public Class ComClass
373  * Public Structure Book
374  * <MarshalAs(UnmanagedType.BStr)> _
375  * Public title As String
376  * Public cost As Integer
377  * End Structure
378  * Public Function getBook() As Book
379  * Dim book As New Book
380  * book.title = "The Ruby Book"
381  * book.cost = 20
382  * Return book
383  * End Function
384  * End Class
385  *
386  * then, the result of WIN32OLE_RECORD#typename is the following:
387  *
388  * require 'win32ole'
389  * obj = WIN32OLE.new('ComServer.ComClass')
390  * book = obj.getBook
391  * book.typename # => "Book"
392  *
393  */
394 static VALUE
395 folerecord_typename(VALUE self)
396 {
397  return rb_ivar_get(self, rb_intern("typename"));
398 }
399 
400 static VALUE
401 olerecord_ivar_get(VALUE self, VALUE name)
402 {
403  VALUE fields;
404  fields = rb_ivar_get(self, rb_intern("fields"));
405  return rb_hash_fetch(fields, name);
406 }
407 
408 static VALUE
409 olerecord_ivar_set(VALUE self, VALUE name, VALUE val)
410 {
411  long len;
412  char *p;
413  VALUE fields;
414  len = RSTRING_LEN(name);
415  p = RSTRING_PTR(name);
416  if (p[len-1] == '=') {
417  name = rb_str_subseq(name, 0, len-1);
418  }
419  fields = rb_ivar_get(self, rb_intern("fields"));
420  rb_hash_fetch(fields, name);
421  return rb_hash_aset(fields, name, val);
422 }
423 
424 /*
425  * call-seq:
426  * WIN32OLE_RECORD#method_missing(name)
427  *
428  * Returns value specified by the member name of VT_RECORD OLE variable.
429  * Or sets value specified by the member name of VT_RECORD OLE variable.
430  * If the member name is not correct, KeyError exception is raised.
431  *
432  * If COM server in VB.NET ComServer project is the following:
433  *
434  * Imports System.Runtime.InteropServices
435  * Public Class ComClass
436  * Public Structure Book
437  * <MarshalAs(UnmanagedType.BStr)> _
438  * Public title As String
439  * Public cost As Integer
440  * End Structure
441  * End Class
442  *
443  * Then getting/setting value from Ruby is as the following:
444  *
445  * obj = WIN32OLE.new('ComServer.ComClass')
446  * book = WIN32OLE_RECORD.new('Book', obj)
447  * book.title # => nil ( book.method_missing(:title) is invoked. )
448  * book.title = "Ruby" # ( book.method_missing(:title=, "Ruby") is invoked. )
449  */
450 static VALUE
451 folerecord_method_missing(int argc, VALUE *argv, VALUE self)
452 {
453  VALUE name;
454  rb_check_arity(argc, 1, 2);
455  name = rb_sym2str(argv[0]);
456 
457 #if SIZEOF_SIZE_T > SIZEOF_LONG
458  {
459  size_t n = strlen(StringValueCStr(name));
460  if (n >= LONG_MAX) {
461  rb_raise(rb_eRuntimeError, "too long member name");
462  }
463  }
464 #endif
465 
466  if (argc == 1) {
467  return olerecord_ivar_get(self, name);
468  } else if (argc == 2) {
469  return olerecord_ivar_set(self, name, argv[1]);
470  }
471  return Qnil;
472 }
473 
474 /*
475  * call-seq:
476  * WIN32OLE_RECORD#ole_instance_variable_get(name)
477  *
478  * Returns value specified by the member name of VT_RECORD OLE object.
479  * If the member name is not correct, KeyError exception is raised.
480  * If you can't access member variable of VT_RECORD OLE object directly,
481  * use this method.
482  *
483  * If COM server in VB.NET ComServer project is the following:
484  *
485  * Imports System.Runtime.InteropServices
486  * Public Class ComClass
487  * Public Structure ComObject
488  * Public object_id As Ineger
489  * End Structure
490  * End Class
491  *
492  * and Ruby Object class has title attribute:
493  *
494  * then accessing object_id of ComObject from Ruby is as the following:
495  *
496  * srver = WIN32OLE.new('ComServer.ComClass')
497  * obj = WIN32OLE_RECORD.new('ComObject', server)
498  * # obj.object_id returns Ruby Object#object_id
499  * obj.ole_instance_variable_get(:object_id) # => nil
500  *
501  */
502 static VALUE
503 folerecord_ole_instance_variable_get(VALUE self, VALUE name)
504 {
505  VALUE sname;
506  if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
507  rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
508  }
509  sname = name;
510  if (RB_TYPE_P(name, T_SYMBOL)) {
511  sname = rb_sym2str(name);
512  }
513  return olerecord_ivar_get(self, sname);
514 }
515 
516 /*
517  * call-seq:
518  * WIN32OLE_RECORD#ole_instance_variable_set(name, val)
519  *
520  * Sets value specified by the member name of VT_RECORD OLE object.
521  * If the member name is not correct, KeyError exception is raised.
522  * If you can't set value of member of VT_RECORD OLE object directly,
523  * use this method.
524  *
525  * If COM server in VB.NET ComServer project is the following:
526  *
527  * Imports System.Runtime.InteropServices
528  * Public Class ComClass
529  * <MarshalAs(UnmanagedType.BStr)> _
530  * Public title As String
531  * Public cost As Integer
532  * End Class
533  *
534  * then setting value of the `title' member is as following:
535  *
536  * srver = WIN32OLE.new('ComServer.ComClass')
537  * obj = WIN32OLE_RECORD.new('Book', server)
538  * obj.ole_instance_variable_set(:title, "The Ruby Book")
539  *
540  */
541 static VALUE
542 folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val)
543 {
544  VALUE sname;
545  if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
546  rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
547  }
548  sname = name;
549  if (RB_TYPE_P(name, T_SYMBOL)) {
550  sname = rb_sym2str(name);
551  }
552  return olerecord_ivar_set(self, sname, val);
553 }
554 
555 /*
556  * call-seq:
557  * WIN32OLE_RECORD#inspect -> String
558  *
559  * Returns the OLE struct name and member name and the value of member
560  *
561  * If COM server in VB.NET ComServer project is the following:
562  *
563  * Imports System.Runtime.InteropServices
564  * Public Class ComClass
565  * <MarshalAs(UnmanagedType.BStr)> _
566  * Public title As String
567  * Public cost As Integer
568  * End Class
569  *
570  * then
571  *
572  * srver = WIN32OLE.new('ComServer.ComClass')
573  * obj = WIN32OLE_RECORD.new('Book', server)
574  * obj.inspect # => <WIN32OLE_RECORD(ComClass) {"title" => nil, "cost" => nil}>
575  *
576  */
577 static VALUE
578 folerecord_inspect(VALUE self)
579 {
580  VALUE tname;
581  VALUE field;
582  tname = folerecord_typename(self);
583  if (tname == Qnil) {
584  tname = rb_inspect(tname);
585  }
586  field = rb_inspect(folerecord_to_h(self));
587  return rb_sprintf("#<WIN32OLE_RECORD(%"PRIsVALUE") %"PRIsVALUE">",
588  tname,
589  field);
590 }
591 
592 void
594 {
595  cWIN32OLE_RECORD = rb_define_class("WIN32OLE_RECORD", rb_cObject);
596  rb_define_alloc_func(cWIN32OLE_RECORD, folerecord_s_allocate);
597  rb_define_method(cWIN32OLE_RECORD, "initialize", folerecord_initialize, 2);
598  rb_define_method(cWIN32OLE_RECORD, "to_h", folerecord_to_h, 0);
599  rb_define_method(cWIN32OLE_RECORD, "typename", folerecord_typename, 0);
600  rb_define_method(cWIN32OLE_RECORD, "method_missing", folerecord_method_missing, -1);
601  rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_get", folerecord_ole_instance_variable_get, 1);
602  rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_set", folerecord_ole_instance_variable_set, 2);
603  rb_define_method(cWIN32OLE_RECORD, "inspect", folerecord_inspect, 0);
604 }
#define T_SYMBOL
Definition: ruby.h:508
VALUE eWIN32OLERuntimeError
Definition: win32ole_error.h:4
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1138
IRecordInfo * pri
size_t strlen(const char *)
int count
Definition: encoding.c:56
VALUE create_win32ole_record(IRecordInfo *pri, void *prec)
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
Definition: st.h:99
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
VALUE cWIN32OLE
Definition: win32ole.c:37
ITypeLib * itypelib(VALUE self)
#define rb_check_arity
Definition: intern.h:298
LPWSTR ole_vstr2wc(VALUE vstr)
Definition: win32ole.c:864
VALUE cWIN32OLE_TYPELIB
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3159
VALUE rb_hash_fetch(VALUE hash, VALUE key)
Definition: hash.c:917
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:656
void ole_rec2variant(VALUE rec, VARIANT *var)
HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
Definition: win32ole.c:3917
VALUE rb_eArgError
Definition: error.c:802
void rb_hash_foreach(VALUE hash, int(*func)(ANYARGS), VALUE farg)
Definition: hash.c:385
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
#define ALLOC_N(type, n)
Definition: ruby.h:1587
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
void Init_win32ole_record(void)
#define WC2VSTR(x)
Definition: win32ole.h:130
int argc
Definition: ruby.c:187
#define ALLOCA_N(type, n)
Definition: ruby.h:1593
#define LONG_MAX
Definition: ruby.h:189
VALUE ole_variant2val(VARIANT *pvar)
Definition: win32ole.c:1417
#define OLE_ADDREF(X)
Definition: win32ole.h:97
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2406
#define RSTRING_LEN(str)
Definition: ruby.h:971
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1452
VALUE rb_hash_new(void)
Definition: hash.c:424
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
#define PRIsVALUE
Definition: ruby.h:135
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
VALUE rb_eTypeError
Definition: error.c:801
register unsigned int len
Definition: zonetab.h:51
#define StringValueCStr(v)
Definition: ruby.h:571
#define RSTRING_PTR(str)
Definition: ruby.h:975
#define OLE_RELEASE(X)
Definition: win32ole.h:98
int size
Definition: encoding.c:57
VALUE cWIN32OLE_RECORD
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE rb_eRuntimeError
Definition: error.c:800
#define T_STRING
Definition: ruby.h:496
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1175
const char * name
Definition: nkf.c:208
#define StringValuePtr(v)
Definition: ruby.h:570
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
free(psz)
#define OLE_FREE(x)
Definition: win32ole.h:99
char ** argv
Definition: ruby.c:188
#define rb_sym2str(sym)
Definition: console.c:107
void ole_val2variant(VALUE val, VARIANT *var)
Definition: win32ole.c:1248