+++ /dev/null
-//
-// (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, Object* 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,
- Object* 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,
- Object* 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,
- Object* 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;
-}
-
-Object* InvokeBridge::NewString(System::String* s)
-{
- System::String* c = System::String::Copy(s);
- return dynamic_cast<Object*>(c);
-}
-
-Array* InvokeBridge::NewArgArray(int sz)
-{
- return Array::CreateInstance(__typeof(Object), sz);
-}
-
-void InvokeBridge::SetArg(Object* arr[], Object* val, int idx)
-{
- arr->SetValue(val,idx);
-}
-
-Object* InvokeBridge::GetArg(Object* arr[], int idx)
-{
- return arr->GetValue(idx);
-}
-
-} /* namespace */