Chinaunix首页 | 论坛 | 博客
  • 博客访问: 523351
  • 博文数量: 576
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5020
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(576)

文章存档

2011年(1)

2008年(575)

我的朋友

分类:

2008-10-14 14:54:16

?MyLib.cs
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);
      }
   }
}

?Loading MyLib Dynamically
#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);
   };
}

?PluginMgr

PluginMgr.h
#pragma once
#include 

using 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
};
PluginMgr.cpp
#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;
}

?Using ON_COMMAND_RANGE
#include "StdAfx.h"
#include "View.h"
#include "PGEdit.h"

#using 
using 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);
      }
   }
}

?CapsPlugin
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---------------------


阅读(404) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~