分类:
2008-10-14 14:54:16
using System; using System.Reflection; using System.Runtime.CompilerServices; namespace MyLib { // Class that exports a single static function public class MyClass { public MyClass(){} static public void SayHello(String who) { Console.WriteLine("Hello, world, from {0}", who); } } }
#using#using #include #include #include using namespace System; using namespace System::Reflection; void main () { try { // Load library dynamically: Assembly* a = Assembly::Load("MyLib"); if (a) { Console::WriteLine("Assembly = {0}", a); Type* t = a->GetType("MyLib.MyClass"); if (t) { Console::WriteLine("Type = {0}", t); MethodInfo* m = t->GetMethod("SayHello"); if (m) { Console::WriteLine("Method = {0}\n", m); String* args[] = {"Test2"}; m->Invoke(NULL, args); } else { printf("Can't find SayHello!\n"); } } else { printf("Can't find MyLib.MyClass!\n"); } } else { printf("Can't load MyLib!\n"); } } catch (Exception* e) { Console::WriteLine("*** Oops: Exception occurred: {0}", e); } }
?ITextPlugin
#pragma once using namespace System; using namespace System::ComponentModel; namespace TextPlugin { // plug-in interface definition public __gc __interface ITextPlugin { [ReadOnly(true)] __property String* get_MenuName(); [ReadOnly(true)] __property String* get_MenuPrompt(); String* Transform(String* text); }; }
#pragma once #includePluginMgr.cppusing namespace std; using namespace System; using namespace System::Collections; // STL vector of managed Objects, wrapped as gcroot handle typedef vector > PLUGINLIST; //////////////// // .NET Plug-in Manager. This class will load all the DLLs in a folder, // looking for assemblies that contain classes that implement a specific // interface, and will instantiate any such classes it finds, adding them // to a list (STL vector). Note this is a native class, which is why I // have to use gcroot, because a native class can't hold pointers to // managed objects. // class CPluginMgr { public: CPluginMgr(LPCTSTR dir=NULL); virtual ~CPluginMgr(); PLUGINLIST m_objects; // list (vector) of plug-in objects // load all DLLs that implement given interface. int LoadAll(Type* iface, int nReserve=10); // Get ith plug-in Object* CPluginMgr::GetPlugin(int i) { return m_objects[i]; } // ditto, using [] Object* operator[](int i) { return GetPlugin(i); } protected: // helper: load single plug-in int LoadPlugin(Type* iface, LPCTSTR pathname); CString m_dir; // plug-in directory where DLLs are };
#include "stdafx.h" #include "PluginMgr.h" using namespace System; using namespace System::Reflection; CPluginMgr::CPluginMgr(LPCTSTR dir) : m_dir(dir) { if (m_dir.IsEmpty()) { // default plug-in directory is exedir/PlugIns, where exedir is the // folder containing the executable LPTSTR buf = m_dir.GetBuffer(MAX_PATH); // buffer in which to copy GetModuleFileName(NULL, buf, MAX_PATH); // exe path PathRemoveFileSpec(buf); // remove file name part m_dir.ReleaseBuffer(); // free buffer m_dir += _T("\\PlugIns"); // append "PlugIns" } } CPluginMgr::~CPluginMgr() { } ////////////////// // Load and instantiate all plug-ins that implement a given interface. Note // this will load all DLLs in the plug-in directory, even ones that don't // implement the interface—there's no way to unload an Assembly w/o using // AppDomains. // int CPluginMgr::LoadAll(Type* iface, int nReserve) { ASSERT(iface); ASSERT(iface->IsInterface); m_objects.reserve(nReserve); // for efficiency // Use MFC to find *.dll in the plug-ins directory, and load each one CFileFind libs; CString spec; spec.Format(_T("%s\\*.dll"), m_dir); TRACE(_T("Loading %s\n"), spec); BOOL bMore = libs.FindFile(spec); while (bMore) { bMore = libs.FindNextFile(); LoadPlugin(iface, libs.GetFilePath()); } TRACE(_T("%d plugins found\n"), m_objects.size()); return m_objects.size(); } ////////////////// // Load single DLL file, looking for given interface // int CPluginMgr::LoadPlugin(Type* iface, LPCTSTR pathname) { int count=0; try { Assembly * a = Assembly::LoadFrom(pathname); Type* types[] = a->GetTypes(); for (int i=0; iLength; i++) { Type *type = types[i]; if (iface->IsAssignableFrom(type)) { TRACE(_T("Found type %s in %s\n"), CString(type->Name), pathname); Object* obj = Activator::CreateInstance(type); m_objects.push_back(obj); count++; } } } catch (Exception* e) { TRACE(_T("*** Exception %s loading %s, ignoring\n"), CString(e->ToString()), pathname); } if (!count) TRACE(_T("*** Didn't find %s in %s\n"), CString(iface->Name), pathname); return count; }
#include "StdAfx.h" #include "View.h" #include "PGEdit.h" #usingusing namespace TextPlugin; IMPLEMENT_DYNCREATE(CMyView, CEditView) BEGIN_MESSAGE_MAP(CMyView, CEditView) ON_COMMAND_RANGE(IDC_PLUGIN_BASE, IDC_PLUGIN_END, OnPluginCmd) ON_UPDATE_COMMAND_UI_RANGE(IDC_PLUGIN_BASE, IDC_PLUGIN_END, OnPluginCmdUI) END_MESSAGE_MAP() void CMyView::OnPluginCmd(UINT id) { CEdit& edit = GetEditCtrl(); int begin,end; edit.GetSel(begin,end); if (end>begin) { Object* obj = theApp.m_plugins.GetPlugin(id - IDC_PLUGIN_BASE); ASSERT(obj); ITextPlugin* plugin = dynamic_cast (obj); if (plugin) { CString text; edit.GetWindowText(text); text = text.Mid(begin, end-begin); text = plugin->Transform(text); edit.ReplaceSel(text); edit.SetSel(begin,end); } } }
using System; using System.Reflection; using System.Runtime.CompilerServices; using TextPlugin; public class CapsPlugin : ITextPlugin { public CapsPlugin() {} public String MenuName { get { return "Uppercase"; } } public String MenuPrompt { get { return "Convert selected text to ALL UPPERCASE"; } } public String Transform(String text) { return text.ToUpper(); } }
--------------------next---------------------