Ok I am getting in over my head here trying to make a CommandMethod attribute. I have created a custom Attribute class called TesterAttribute that has one property string GlobalName. I am able to search an assembly for the attribute, get the method, and global name. I can also invoke the method.
My Question is how can I register a managed method pointer with sds_regfunc() (read: acedRegFunc() ) so the method can be called from the command line? I am even making sense ?
Here is what I have so far.
public ref class NetLoader
{
internal:
static Hashtable ^ht = gcnew Hashtable();
public:
NetLoader(void)
{
}
static NetLoader(void)
{
Initialize();
}
static void Initialize()
{
System::AppDomain::CurrentDomain->AssemblyLoad +=
gcnew AssemblyLoadEventHandler(NetLoader::OnAssemblyLoad);
}
static void OnAssemblyLoad(Object ^sender, AssemblyLoadEventArgs ^e)
{
ProcessAssembly(e->LoadedAssembly);
}
[SecurityPermission(SecurityAction::LinkDemand, Infrastructure=true)]
static void Load(String ^fileName)
{
System::Reflection::Assembly::LoadFrom(fileName);
}
static void ProcessAssembly(Assembly^ assembly)
{
Type ^tp = DWM::Cad::RuntimeServices::TesterAttribute::typeid;
for each (Type^ t in assembly->GetTypes())
for each (MethodInfo^ m in t->GetMethods())
//for each (Object^ o in m->GetCustomAttributes(tp,true))// nope
for each (Object^ o in m->GetCustomAttributes(true))
{
if (o->ToString() == tp->ToString()) //what a hack
{
TesterAttribute ^att = static_cast<TesterAttribute^>(o);//ok
if( !ht->ContainsKey((String^)att->GlobalName) && !ht->ContainsValue((MethodInfo^)m) )
{
ht->Add((String^)att->GlobalName , (MethodInfo^)m);
m->Invoke(nullptr, nullptr);//yeehaw it works
//see acedDefun() and acedRegFunc()
sds_defun((char*)(void*)Marshal::StringToHGlobalAnsi(att->GlobalName) , ht->Count);
sds_regfunc(m->Invoke(nullptr,nullptr) , ht->Count);
}
else
{
Utilities::WriteMessage("\nCommand " + att->GlobalName + " Already registered");//ok
}
}
}
}
};