4 // Dynamic invocation helper classes. The details of how
5 // to access the .NET object model via the Reflection API
6 // is taken care of by Invoker.{h,cpp}
12 static TypeName* ParseType(String* str) {
16 // Console::WriteLine("x{0}y", str);
17 TypeName* typeName = new TypeName();
19 if ( str->get_Chars(0) == '[' ) {
20 endPos = str->IndexOf(']');
22 typeName->m_assembly = str->Substring(1,endPos-1);
23 typeName->m_length = endPos+1;
25 String* delimStr = " ,()";
26 Char delims __gc [] = delimStr->ToCharArray();
28 endPos = str->IndexOfAny(delims,curPos);
29 // Console::WriteLine("{0} {1} x{2}x", __box(endPos), __box(curPos), str);
31 typeName->m_class = str->Substring(curPos);
33 typeName->m_class = str->Substring(curPos,endPos-curPos);
36 // typeName->m_class = str->Substring(curPos,endPos-curPos);
37 typeName->m_length += endPos-curPos;
42 // Method: GetType(String* typeName);
44 // Purpose: Assembly-savvy version of Type::GetType()
46 Type* InvokeBridge::GetType(String* typeName) {
49 Type* t = Type::GetType(typeName);
51 } catch (Exception*) {
55 for (int i=0;i < InvokeBridge::m_assemblies->Count; i++) {
57 String* stuff = String::Format("{0},{1}",typeName,InvokeBridge::m_assemblies->get_Item(i)->ToString());
58 // Console::WriteLine(stuff);
59 Type* t = Type::GetType(stuff);
63 } catch (Exception*) {
71 // Method: CreateInstance(String* typeName, Object* [])
73 // Purpose: Assembly-savvy invocation of Activator::CreateInstance
74 Object* InvokeBridge::CreateInstance(TypeName* typeName,
78 Type* t = InvokeBridge::GetType(typeName->toStdString());
80 // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
83 Assembly* localA = Assembly::LoadFrom(typeName->m_assembly);
84 t = localA->GetType(typeName->m_class);
85 } catch (Exception* e) {
92 AppDomain* currentDomain = AppDomain::CurrentDomain;
94 // Assembly* stuff[] = currentDomain->GetAssemblies();
95 // for (int i=0;i < stuff.Length; i++) {
96 // Console::WriteLine("x{0} y{1}", stuff[i]->ToString(), stuff[i]->FullName);
98 // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
99 Assembly* localA = Assembly::LoadWithPartialName("HugsAssembly");
100 t = localA->GetType(typeName->m_class);
101 // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
102 } catch (Exception*) {
109 Object* o =Activator::CreateInstance(t,(Object* [])args);
111 } catch (Exception* e) {
112 Console::WriteLine("Failure: {0}", e);
119 // Method: CreateObject(String* objSpec, Object* args[])
121 // Purpose: Given a fully qualified name of a class/type, try
122 // to create an instance of it.
124 Object* InvokeBridge::CreateObject(String* assemName,
128 Object* instance = 0;
130 // Unravel the name of the class/type.
131 TypeName* typeName = ParseType(objSpec);
133 if (assemName != 0 && assemName->Length > 0) {
134 typeName->m_assembly = assemName;
137 // Try creating the instance..
139 instance = InvokeBridge::CreateInstance(typeName,(Object* [])args);
140 } catch (Exception* e) {
141 Console::WriteLine("Unable to create instance \"{0}\" {1}", objSpec, e);
145 Console::WriteLine("Unable to create instance \"{0}\"", objSpec);
151 // Method: InvokeMethod
153 // Purpose: Given a pointer to an already created object, look up
154 // one of its method. If found, invoke the method passing it
155 // 'args' as arguments.
158 InvokeBridge::InvokeMethod(Object* obj,
161 // Get the methods from the type
162 MethodInfo* methods __gc[] = obj->GetType()->GetMethods();
166 Console::WriteLine("InvokeMethod: No matching types found");
170 System::Reflection::BindingFlags flgs
171 = (System::Reflection::BindingFlags) // why do I need to cast?
172 (System::Reflection::BindingFlags::Public |
173 System::Reflection::BindingFlags::NonPublic |
174 System::Reflection::BindingFlags::Instance |
175 System::Reflection::BindingFlags::Static |
176 System::Reflection::BindingFlags::InvokeMethod);
178 /* Caller is assumed to catch any exceptions raised. */
179 return obj->GetType()->InvokeMember(methName,
183 (Object __gc* [])args);
187 // Method: InvokeStaticMethod
189 // Purpose: Invoke a static method, given the fully qualified name
190 // of the method (and its arguments). If found, invoke the
191 // method passing it 'args' as arguments.
193 Object* InvokeBridge::InvokeStaticMethod(String* assemName,
194 String* typeAndMethName,
197 // Get the methods from the type
198 MethodInfo* methods __gc[];
201 int lastDot = typeAndMethName->LastIndexOf('.');
202 String* className = typeAndMethName->Substring(0,lastDot);
203 String* methName = typeAndMethName->Substring(lastDot+1);
205 // Unravel the name of the class/type.
206 TypeName* typeName = ParseType(className);
209 if (assemName != 0 && assemName->Length > 0) {
210 typeName->m_assembly = assemName;
214 t = InvokeBridge::GetType(typeName->toStdString());
218 Assembly* localA = Assembly::LoadFrom(typeName->m_assembly);
219 t = localA->GetType(typeName->m_class);
220 // Console::WriteLine("InvokeStaticMethod: Type {0} found", t);
221 } catch (Exception* e) {
227 methods = t->GetMethods();
229 Console::WriteLine("InvokeStaticMethod: Type {0} not found", className);
232 } catch (Exception *e) {
233 Console::WriteLine("InvokeStaticMethod: Type {0} not found", className);
237 System::Reflection::BindingFlags flgs
238 = (System::Reflection::BindingFlags) // why do I need to cast?
239 (System::Reflection::BindingFlags::DeclaredOnly |
240 System::Reflection::BindingFlags::Public |
241 System::Reflection::BindingFlags::NonPublic |
242 System::Reflection::BindingFlags::Static |
243 System::Reflection::BindingFlags::InvokeMethod);
245 return t->InvokeMember(methName,
249 (Object __gc* [])args);
255 // Purpose: Fetch the (boxed) value of named field of a given object.
257 Object* InvokeBridge::GetField(Object* obj, System::String* fieldName) {
259 FieldInfo* fInfo = obj->GetType()->GetField(fieldName);
260 return fInfo->GetValue(obj);
264 // Method: GetStaticField
266 // Purpose: Fetch the (boxed) value of named static field.
268 Object* InvokeBridge::GetStaticField(System::String* clsName,
269 System::String* fieldName) {
271 Type* ty = InvokeBridge::GetType(clsName);
272 System::Reflection::BindingFlags static_field_flgs
273 = (System::Reflection::BindingFlags)
274 (System::Reflection::BindingFlags::Public |
275 System::Reflection::BindingFlags::NonPublic |
276 System::Reflection::BindingFlags::FlattenHierarchy |
277 System::Reflection::BindingFlags::Static);
279 FieldInfo* fInfo = ty->GetField(fieldName, static_field_flgs);
280 return fInfo->GetValue(0); // according to doc, ok to pass any val here.
286 // Purpose: Replace the (boxed) value of named field of a given object.
288 void InvokeBridge::SetField(Object* obj, System::String* fieldName, Object* val) {
290 FieldInfo* fInfo = obj->GetType()->GetField(fieldName);
291 fInfo->SetValue(obj,val);
296 // Method: SetStaticField
298 // Purpose: Replace the (boxed) value of named static field.
300 void InvokeBridge::SetStaticField(System::String* clsName,
301 System::String* fieldName,
304 Type* ty = InvokeBridge::GetType(clsName);
305 System::Reflection::BindingFlags static_field_flgs
306 = (System::Reflection::BindingFlags)
307 (System::Reflection::BindingFlags::Public |
308 System::Reflection::BindingFlags::NonPublic |
309 System::Reflection::BindingFlags::FlattenHierarchy |
310 System::Reflection::BindingFlags::Static);
312 FieldInfo* fInfo = ty->GetField(fieldName,static_field_flgs);
313 fInfo->SetValue(0,val);
317 Object* InvokeBridge::NewString(System::String* s)
319 System::String* c = System::String::Copy(s);
320 return dynamic_cast<Object*>(c);
323 Array* InvokeBridge::NewArgArray(int sz)
325 return Array::CreateInstance(__typeof(Object), sz);
328 void InvokeBridge::SetArg(Object* arr[], Object* val, int idx)
330 arr->SetValue(val,idx);
333 Object* InvokeBridge::GetArg(Object* arr[], int idx)
335 return arr->GetValue(idx);