-
Notifications
You must be signed in to change notification settings - Fork 1
/
RubyObject.h
162 lines (145 loc) · 4.98 KB
/
RubyObject.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
* Copyright(c) 2000 arton
*
* You may distribute under the terms of either the GNU General Public
* License
*
* $Date: 2006-11-14 02:21:15 +0900 (火, 14 11 2006) $
*/
#ifndef RUBYOBJECT_HEADER
#define RUBYOBJECT_HEADER
class CRubyObject;
typedef std::map<std::string, ID> RubyMethodMap;
typedef std::map<std::string, ID>::iterator RubyMethodMapIter;
typedef std::map<std::string, CRubyObject*> RubyObjectMap;
typedef std::map<std::string, CRubyObject*>::iterator RubyObjectMapIter;
// COM -> Ruby wrapper dispatch
// This class has no TypeLibrary. So I can't use typelib marshaling.
// Instead it, IRubyEngine can handle GIT marshaling for the caller object,
// So, in this class, I simply put Free Thread Marshaler.
//
// In GlobalRubyScript, there is no need to marshal interface (only local),
// so no Free Thread Marshaler is required.
class CRubyObject : public IDispatchEx
{
public:
static CRubyObject* CreateRubyObject(IRubyEngine* pengine, VALUE val);
CRubyObject(IRubyEngine* pengine, VALUE val, bool wrapperObject = true, IDispatch* pDisp = NULL);
~CRubyObject();
HRESULT STDMETHODCALLTYPE QueryInterface(
const IID & riid,
void **ppvObj);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
// IDispatch
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ UINT __RPC_FAR *pctinfo);
HRESULT STDMETHODCALLTYPE GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr);
HRESULT STDMETHODCALLTYPE GetDispID(
/* [in] */ BSTR bstrName,
/* [in] */ DWORD grfdex,
/* [out] */ DISPID __RPC_FAR *pid)
{
HRESULT hr = GetIDsOfNames(IID_NULL, &bstrName, 1, LOCALE_SYSTEM_DEFAULT, pid);
return hr;
}
HRESULT STDMETHODCALLTYPE InvokeEx(
/* [in] */ DISPID id,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [in] */ DISPPARAMS __RPC_FAR *pdp,
/* [out] */ VARIANT __RPC_FAR *pvarRes,
/* [out] */ EXCEPINFO __RPC_FAR *pei,
/* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller)
{
#ifdef __IRubyWrapper_INTERFACE_DEFINED__
if (pspCaller)
m_pEngine->RegisterServiceProvider(pspCaller);
#endif
HRESULT hr = Invoke(id, IID_NULL, lcid, wFlags, pdp, pvarRes, pei, NULL);
#ifdef __IRubyWrapper_INTERFACE_DEFINED__
if (pspCaller)
m_pEngine->UnregisterServiceProvider();
#endif
return hr;
}
HRESULT STDMETHODCALLTYPE DeleteMemberByName(
/* [in] */ BSTR bstr,
/* [in] */ DWORD grfdex)
{
ATLTRACENOTIMPL(_T("DeleteMemberByName"));
}
HRESULT STDMETHODCALLTYPE DeleteMemberByDispID(
/* [in] */ DISPID id)
{
ATLTRACENOTIMPL(_T("DeleteMemberByDispID"));
}
HRESULT STDMETHODCALLTYPE GetMemberProperties(
/* [in] */ DISPID id,
/* [in] */ DWORD grfdexFetch,
/* [out] */ DWORD __RPC_FAR *pgrfdex)
{
ATLTRACENOTIMPL(_T("GetMemberProperties"));
}
HRESULT STDMETHODCALLTYPE GetMemberName(
/* [in] */ DISPID id,
/* [out] */ BSTR __RPC_FAR *pbstrName)
{
ATLTRACENOTIMPL(_T("GetMemberName"));
}
HRESULT STDMETHODCALLTYPE GetNextDispID(
/* [in] */ DWORD grfdex,
/* [in] */ DISPID id,
/* [out] */ DISPID __RPC_FAR *pid)
{
ATLTRACENOTIMPL(_T("GetNextDispID"));
}
HRESULT STDMETHODCALLTYPE GetNameSpaceParent(
/* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk)
{
ATLTRACENOTIMPL(_T("GetNameSpaceParent"));
}
inline void ClearEngine() { m_pEngine = NULL; }
static DISPID ConvertDispID(VALUE, DISPID, WORD);
private:
IRubyEngine* m_pEngine;
CComPtr<IDispatch> m_pDisp;
#ifdef __IRubyWrapper_INTERFACE_DEFINED__
IRubyEngine* m_pEngineVal;
CComPtr<IUnknown> m_pUnkMarshaler;
#else
void GetValue(VALUE, VARIANT*, IActiveScriptError*);
void GetEnum(VALUE, VARIANT*, IActiveScriptError*);
ID m_idMethodDefined;
ID m_idMethods, m_idPrivMethods;
ID m_idSize;
DISPID searchMethod(VALUE obj, LPCSTR psz);
static VALUE add_item(VALUE item, VALUE ary);
static VALUE InvokeRuby(VALUE Param);
static VALUE val2var(VALUE Param);
static IActiveScriptError* FetchErrorInfo();
#endif
long m_lCount;
VALUE m_valueKlass;
bool m_fRubyObject;
RubyMethodMap m_mapMethods;
};
#endif