//// (c) 2002-2003, sof.//// Dynamic invocation helper classes. The details of how// to access the .NET object model via the Reflection API// is taken care of by Invoker.{h,cpp}//#include "Invoker.h" namespace DynInvoke { static TypeName* ParseType(String* str) { int curPos = 0; int endPos; // Console::WriteLine("x{0}y", str); TypeName* typeName = new TypeName(); if ( str->get_Chars(0) == '[' ) { endPos = str->IndexOf(']'); curPos = endPos + 1; typeName->m_assembly = str->Substring(1,endPos-1); typeName->m_length = endPos+1; } String* delimStr = " ,()"; Char delims __gc [] = delimStr->ToCharArray(); endPos = str->IndexOfAny(delims,curPos); // Console::WriteLine("{0} {1} x{2}x", __box(endPos), __box(curPos), str); if ( endPos == -1 ) { typeName->m_class = str->Substring(curPos); } else { typeName->m_class = str->Substring(curPos,endPos-curPos); } // typeName->m_class = str->Substring(curPos,endPos-curPos); typeName->m_length += endPos-curPos; return typeName;} // Method: GetType(String* typeName);// // Purpose: Assembly-savvy version of Type::GetType()//Type* InvokeBridge::GetType(String* typeName) { try { Type* t = Type::GetType(typeName); if (t) return t; } catch (Exception*) { ; } for (int i=0;i < InvokeBridge::m_assemblies->Count; i++) { try { String* stuff = String::Format("{0},{1}",typeName,InvokeBridge::m_assemblies->get_Item(i)->ToString()); // Console::WriteLine(stuff); Type* t = Type::GetType(stuff); if (t) { return t; } } catch (Exception*) { continue; } } return 0;} //// Method: CreateInstance(String* typeName, Object* [])//// Purpose: Assembly-savvy invocation of Activator::CreateInstanceObject* InvokeBridge::CreateInstance(TypeName* typeName, Object* args[]) { Object* instance = 0; Type* t = InvokeBridge::GetType(typeName->toStdString()); // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t); if (!t) { try { Assembly* localA = Assembly::LoadFrom(typeName->m_assembly); t = localA->GetType(typeName->m_class); } catch (Exception* e) { ; } } if (!t) { try { AppDomain* currentDomain = AppDomain::CurrentDomain; // Assembly* stuff[] = currentDomain->GetAssemblies(); // for (int i=0;i < stuff.Length; i++) { // Console::WriteLine("x{0} y{1}", stuff[i]->ToString(), stuff[i]->FullName); // } // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t); Assembly* localA = Assembly::LoadWithPartialName("HugsAssembly"); t = localA->GetType(typeName->m_class); // Console::WriteLine("x{0} y{1}", typeName->toStdString(), t); } catch (Exception*) { ; } } if (t) { try { Object* o =Activator::CreateInstance(t,(Object* [])args); return o; } catch (Exception* e) { Console::WriteLine("Failure: {0}", e); return 0; } }} //// Method: CreateObject(String* objSpec, Array* args)//// Purpose: Given a fully qualified name of a class/type, try// to create an instance of it.//Object* InvokeBridge::CreateObject(String* assemName, String* objSpec, Array* args) { Object* instance = 0; // Unravel the name of the class/type. TypeName* typeName = ParseType(objSpec); if (assemName != 0 && assemName->Length > 0) { typeName->m_assembly = assemName; } // Try creating the instance.. try { instance = InvokeBridge::CreateInstance(typeName,(Object* [])args); } catch (Exception* e) { Console::WriteLine("Unable to create instance \"{0}\" {1}", objSpec, e); throw(e); } if (!instance) { Console::WriteLine("Unable to create instance \"{0}\"", objSpec); } return instance;} //// Method: InvokeMethod// // Purpose: Given a pointer to an already created object, look up// one of its method. If found, invoke the method passing it// 'args' as arguments.//Object*InvokeBridge::InvokeMethod(Object* obj, String* methName, Array* args) { // Get the methods from the type MethodInfo* methods __gc[] = obj->GetType()->GetMethods(); MethodInfo* mInfo; if (!methods) { Console::WriteLine("InvokeMethod: No matching types found"); return 0; } System::Reflection::BindingFlags flgs = (System::Reflection::BindingFlags) // why do I need to cast? (System::Reflection::BindingFlags::Public | System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::Instance | System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::InvokeMethod); /* Caller is assumed to catch any exceptions raised. */ return obj->GetType()->InvokeMember(methName, flgs, 0, obj, (Object __gc* [])args);} //// Method: InvokeStaticMethod// // Purpose: Invoke a static method, given the fully qualified name// of the method (and its arguments). If found, invoke the// method passing it 'args' as arguments.//Object* InvokeBridge::InvokeStaticMethod(String* assemName, String* typeAndMethName, Array* args) { // Get the methods from the type MethodInfo* methods __gc[]; MethodInfo* mInfo; int lastDot = typeAndMethName->LastIndexOf('.'); String* className = typeAndMethName->Substring(0,lastDot); String* methName = typeAndMethName->Substring(lastDot+1); // Unravel the name of the class/type. TypeName* typeName = ParseType(className); Type* t; if (assemName != 0 && assemName->Length > 0) { typeName->m_assembly = assemName; } try { t = InvokeBridge::GetType(typeName->toStdString()); if (!t) { try { Assembly* localA = Assembly::LoadFrom(typeName->m_assembly); t = localA->GetType(typeName->m_class); // Console::WriteLine("InvokeStaticMethod: Type {0} found", t); } catch (Exception* e) { ; } } if (t) { methods = t->GetMethods(); } else { Console::WriteLine("InvokeStaticMethod: Type {0} not found", className); return 0; } } catch (Exception *e) { Console::WriteLine("InvokeStaticMethod: Type {0} not found", className); throw(e); } System::Reflection::BindingFlags flgs = (System::Reflection::BindingFlags) // why do I need to cast? (System::Reflection::BindingFlags::DeclaredOnly | System::Reflection::BindingFlags::Public | System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::InvokeMethod); return t->InvokeMember(methName, flgs, 0, 0, (Object __gc* [])args);} //// Method: GetField//// Purpose: Fetch the (boxed) value of named field of a given object.//Object* InvokeBridge::GetField(Object* obj, System::String* fieldName) { FieldInfo* fInfo = obj->GetType()->GetField(fieldName); return fInfo->GetValue(obj);} //// Method: GetStaticField//// Purpose: Fetch the (boxed) value of named static field.//Object* InvokeBridge::GetStaticField(System::String* clsName, System::String* fieldName) { Type* ty = InvokeBridge::GetType(clsName); System::Reflection::BindingFlags static_field_flgs = (System::Reflection::BindingFlags) (System::Reflection::BindingFlags::Public | System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::FlattenHierarchy | System::Reflection::BindingFlags::Static); FieldInfo* fInfo = ty->GetField(fieldName, static_field_flgs); return fInfo->GetValue(0); // according to doc, ok to pass any val here.} //// Method: SetField//// Purpose: Replace the (boxed) value of named field of a given object.//void InvokeBridge::SetField(Object* obj, System::String* fieldName, Object* val) { FieldInfo* fInfo = obj->GetType()->GetField(fieldName); fInfo->SetValue(obj,val); return;} //// Method: SetStaticField//// Purpose: Replace the (boxed) value of named static field.//void InvokeBridge::SetStaticField(System::String* clsName, System::String* fieldName, Object* val) { Type* ty = InvokeBridge::GetType(clsName); System::Reflection::BindingFlags static_field_flgs = (System::Reflection::BindingFlags) (System::Reflection::BindingFlags::Public | System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::FlattenHierarchy | System::Reflection::BindingFlags::Static); FieldInfo* fInfo = ty->GetField(fieldName,static_field_flgs); fInfo->SetValue(0,val); return;} Array* InvokeBridge::NewArgArray(int sz){ return Array::CreateInstance(__typeof(Object), sz); } void InvokeBridge::SetArg(Array* arr, Object* val, int idx){ arr->SetValue(val,idx);} Object* InvokeBridge::GetArg(Array* arr, int idx){ return arr->GetValue(idx);} } /* namespace */
//
// (c) 2002-2003, sof.
//
// Dynamic invocation helper classes. The details of how
// to access the .NET object model via the Reflection API
// is taken care of by Invoker.{h,cpp}
//
#include "Invoker.h"
namespace DynInvoke {
static TypeName* ParseType(String* str) {
int curPos = 0;
int endPos;
// Console::WriteLine("x{0}y", str);
TypeName* typeName = new TypeName();
if ( str->get_Chars(0) == '[' ) {
endPos = str->IndexOf(']');
curPos = endPos + 1;
typeName->m_assembly = str->Substring(1,endPos-1);
typeName->m_length = endPos+1;
}
String* delimStr = " ,()";
Char delims __gc [] = delimStr->ToCharArray();
endPos = str->IndexOfAny(delims,curPos);
// Console::WriteLine("{0} {1} x{2}x", __box(endPos), __box(curPos), str);
if ( endPos == -1 ) {
typeName->m_class = str->Substring(curPos);
} else {
typeName->m_class = str->Substring(curPos,endPos-curPos);
}
// typeName->m_class = str->Substring(curPos,endPos-curPos);
typeName->m_length += endPos-curPos;
return typeName;
}
// Method: GetType(String* typeName);
//
// Purpose: Assembly-savvy version of Type::GetType()
//
Type* InvokeBridge::GetType(String* typeName) {
try {
Type* t = Type::GetType(typeName);
if (t) return t;
} catch (Exception*) {
;
}
for (int i=0;i < InvokeBridge::m_assemblies->Count; i++) {
try {
String* stuff = String::Format("{0},{1}",typeName,InvokeBridge::m_assemblies->get_Item(i)->ToString());
// Console::WriteLine(stuff);
Type* t = Type::GetType(stuff);
if (t) {
return t;
}
} catch (Exception*) {
continue;
}
}
return 0;
}
//
// Method: CreateInstance(String* typeName, Object* [])
//
// Purpose: Assembly-savvy invocation of Activator::CreateInstance
Object* InvokeBridge::CreateInstance(TypeName* typeName,
Object* args[]) {
Object* instance = 0;
Type* t = InvokeBridge::GetType(typeName->toStdString());
// Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
if (!t) {
try {
Assembly* localA = Assembly::LoadFrom(typeName->m_assembly);
t = localA->GetType(typeName->m_class);
} catch (Exception* e) {
;
}
}
if (!t) {
try {
AppDomain* currentDomain = AppDomain::CurrentDomain;
// Assembly* stuff[] = currentDomain->GetAssemblies();
// for (int i=0;i < stuff.Length; i++) {
// Console::WriteLine("x{0} y{1}", stuff[i]->ToString(), stuff[i]->FullName);
// }
// Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
Assembly* localA = Assembly::LoadWithPartialName("HugsAssembly");
t = localA->GetType(typeName->m_class);
// Console::WriteLine("x{0} y{1}", typeName->toStdString(), t);
} catch (Exception*) {
;
}
}
if (t) {
try {
Object* o =Activator::CreateInstance(t,(Object* [])args);
return o;
} catch (Exception* e) {
Console::WriteLine("Failure: {0}", e);
return 0;
}
}
}
//
// Method: CreateObject(String* objSpec, Array* args)
//
// Purpose: Given a fully qualified name of a class/type, try
// to create an instance of it.
//
Object* InvokeBridge::CreateObject(String* assemName,
String* objSpec,
Array* args) {
Object* instance = 0;
// Unravel the name of the class/type.
TypeName* typeName = ParseType(objSpec);
if (assemName != 0 && assemName->Length > 0) {
typeName->m_assembly = assemName;
}
// Try creating the instance..
try {
instance = InvokeBridge::CreateInstance(typeName,(Object* [])args);
} catch (Exception* e) {
Console::WriteLine("Unable to create instance \"{0}\" {1}", objSpec, e);
throw(e);
}
if (!instance) {
Console::WriteLine("Unable to create instance \"{0}\"", objSpec);
}
return instance;
}
//
// Method: InvokeMethod
//
// Purpose: Given a pointer to an already created object, look up
// one of its method. If found, invoke the method passing it
// 'args' as arguments.
//
Object*
InvokeBridge::InvokeMethod(Object* obj,
String* methName,
Array* args) {
// Get the methods from the type
MethodInfo* methods __gc[] = obj->GetType()->GetMethods();
MethodInfo* mInfo;
if (!methods) {
Console::WriteLine("InvokeMethod: No matching types found");
return 0;
}
System::Reflection::BindingFlags flgs
= (System::Reflection::BindingFlags) // why do I need to cast?
(System::Reflection::BindingFlags::Public |
System::Reflection::BindingFlags::NonPublic |
System::Reflection::BindingFlags::Instance |
System::Reflection::BindingFlags::Static |
System::Reflection::BindingFlags::InvokeMethod);
/* Caller is assumed to catch any exceptions raised. */
return obj->GetType()->InvokeMember(methName,
flgs,
0,
obj,
(Object __gc* [])args);
}
//
// Method: InvokeStaticMethod
//
// Purpose: Invoke a static method, given the fully qualified name
// of the method (and its arguments). If found, invoke the
// method passing it 'args' as arguments.
//
Object* InvokeBridge::InvokeStaticMethod(String* assemName,
String* typeAndMethName,
Array* args) {
// Get the methods from the type
MethodInfo* methods __gc[];
MethodInfo* mInfo;
int lastDot = typeAndMethName->LastIndexOf('.');
String* className = typeAndMethName->Substring(0,lastDot);
String* methName = typeAndMethName->Substring(lastDot+1);
// Unravel the name of the class/type.
TypeName* typeName = ParseType(className);
Type* t;
if (assemName != 0 && assemName->Length > 0) {
typeName->m_assembly = assemName;
}
try {
t = InvokeBridge::GetType(typeName->toStdString());
if (!t) {
try {
Assembly* localA = Assembly::LoadFrom(typeName->m_assembly);
t = localA->GetType(typeName->m_class);
// Console::WriteLine("InvokeStaticMethod: Type {0} found", t);
} catch (Exception* e) {
;
}
}
if (t) {
methods = t->GetMethods();
} else {
Console::WriteLine("InvokeStaticMethod: Type {0} not found", className);
return 0;
}
} catch (Exception *e) {
Console::WriteLine("InvokeStaticMethod: Type {0} not found", className);
throw(e);
}
System::Reflection::BindingFlags flgs
= (System::Reflection::BindingFlags) // why do I need to cast?
(System::Reflection::BindingFlags::DeclaredOnly |
System::Reflection::BindingFlags::Public |
System::Reflection::BindingFlags::NonPublic |
System::Reflection::BindingFlags::Static |
System::Reflection::BindingFlags::InvokeMethod);
return t->InvokeMember(methName,
flgs,
0,
0,
(Object __gc* [])args);
}
//
// Method: GetField
//
// Purpose: Fetch the (boxed) value of named field of a given object.
//
Object* InvokeBridge::GetField(Object* obj, System::String* fieldName) {
FieldInfo* fInfo = obj->GetType()->GetField(fieldName);
return fInfo->GetValue(obj);
}
//
// Method: GetStaticField
//
// Purpose: Fetch the (boxed) value of named static field.
//
Object* InvokeBridge::GetStaticField(System::String* clsName,
System::String* fieldName) {
Type* ty = InvokeBridge::GetType(clsName);
System::Reflection::BindingFlags static_field_flgs
= (System::Reflection::BindingFlags)
(System::Reflection::BindingFlags::Public |
System::Reflection::BindingFlags::NonPublic |
System::Reflection::BindingFlags::FlattenHierarchy |
System::Reflection::BindingFlags::Static);
FieldInfo* fInfo = ty->GetField(fieldName, static_field_flgs);
return fInfo->GetValue(0); // according to doc, ok to pass any val here.
}
//
// Method: SetField
//
// Purpose: Replace the (boxed) value of named field of a given object.
//
void InvokeBridge::SetField(Object* obj, System::String* fieldName, Object* val) {
FieldInfo* fInfo = obj->GetType()->GetField(fieldName);
fInfo->SetValue(obj,val);
return;
}
//
// Method: SetStaticField
//
// Purpose: Replace the (boxed) value of named static field.
//
void InvokeBridge::SetStaticField(System::String* clsName,
System::String* fieldName,
Object* val) {
Type* ty = InvokeBridge::GetType(clsName);
System::Reflection::BindingFlags static_field_flgs
= (System::Reflection::BindingFlags)
(System::Reflection::BindingFlags::Public |
System::Reflection::BindingFlags::NonPublic |
System::Reflection::BindingFlags::FlattenHierarchy |
System::Reflection::BindingFlags::Static);
FieldInfo* fInfo = ty->GetField(fieldName,static_field_flgs);
fInfo->SetValue(0,val);
return;
}
Array* InvokeBridge::NewArgArray(int sz)
{
return Array::CreateInstance(__typeof(Object), sz);
}
void InvokeBridge::SetArg(Array* arr, Object* val, int idx)
{
arr->SetValue(val,idx);
}
Object* InvokeBridge::GetArg(Array* arr, int idx)
{
return arr->GetValue(idx);
}
} /* namespace */