COM技术的插件片段
procedure TfrmMain.LoadExplorableClasses;
var
  Count, i : integer;
  Explorable : IExplorable;
  Description : widestring;
  MenuItem : TMenuItem;
begin
  //get explorable server list
  Count := GetExplorableClasses (FExplorableClasses);
  if (Count > 0) then
  begin
    //hide "no explorable items found" menu item
    miNoExplorableItem.Visible := False;
    //get description for each and populate Explore >> submenu
    for i := 1 to Count do
    begin
      //create Explorable plugin
      Explorable := CreateComObject (FExplorableClasses [i]) as IExplorable;
      //get plugin description
      OleCheck (Explorable.GetDescription (Description));
      //create new menu item
      MenuItem := TMenuItem.Create (Self);
      MenuItem.Caption := Description;
      //hide FExplorableClasses array index in Tag
      MenuItem.Tag := i;
      //hook OnClick handler
      MenuItem.OnClick := miExplorableItemClick;
      //add to Explore >> submenu
      miExplore.Add (MenuItem);
    end;
  end;
end;一般插件的写法片段procedure TFrmMain.loadPlugins;
var
  files: tstrings; //存放文件查找结果的文件列表
  i: integer;
  MyPlugin: TMyPlugin; //存放插件信息的自定义的变量
  NewMenu: TMenuItem;
  GetCaption: TGetCaption; //获取插件标题的过程引用
begin
  files := tstringlist.Create; //文件列表
  Plugins := tlist.Create; //建立指针列表
  //查找当前目录的子目录plugins下的 .dll文件,并存于 "files 文件列表"中
  SearchFileExt(Extractfilepath(application.ExeName)+'Plugins\','.dll',files);
  //从文件列表中加载找到的DLL
  for i:=0 to files.Count-1 do
  begin
    myPlugin := TMyPlugin.Create;
    myPlugin.Address := loadlibrary(pchar(files[i])); //装载DLL,返回句柄
    if myplugin.Address=0 then
      showmessage('加载'+files[i]+'失败!')
    else begin
      try
        @GetCaption:=GetProcAddress(myPlugin.Address,'GetCaption'); //通过DLL句柄取得“获取插件标题”过程的入口地址
        myPlugin.Caption:=GetCaption(application.Handle); //返回插件标题
        myPlugin.Call:=GetProcAddress(myPlugin.Address,'ShowDLLForm'); //获取并保存窗体显示过程的入口地址
        Plugins.Add(myPlugin); //加入至指针列表
        //创建菜单,并将菜单标题OnClick事件赋值
        NewMenu:=TMenuItem.Create(self);
        NewMenu.Caption:=myplugin.Caption;
        newmenu.OnClick:=PluginsClick; //绑定事件
        NewMenu.Tag:=i; //用此标识作为插件事件的区分
        plugins1.Add(newMenu); //加入菜单项
      except
        showmessage('初始化失败!');
        raise;
      end;
    end;
  end;
  files.Free;
end;两者有什么区别?优缺点是什么?

解决方案 »

  1.   

    COM的更为简单,不需要LoadLibrary,不过接口效率上COM不如一般DLL的
      

  2.   

    COM只是看起来简单,实际上它该做的事情一个也没有少做,而且为了其它考虑,做得还要多些。
      

  3.   

    除了LoadLibrary之外还有其他的区别吗?关键性的区别?
      

  4.   

    动态加载+契约编程。一个语言支持这两种特性,就可以开发插件了。
    最讨厌COM要写注册表,本质上没有什么区别,有的只是一个是微软帮你订好的规范,一个是要你自己来订。
      

  5.   

    myPlugin.Address := loadlibrary(pchar(files[i])); //装载DLL,返回句柄
    我更看好直接加载DLL!
      

  6.   

    搞这么麻烦?!干脆用TMS Plugin Framework控件了事
      

  7.   

    COM的好处1。接口函数不暴露。
       你使用Depend之类的工具只能分析出4个基本的函数,内部函数是无法获取到的。
    2。可以使用类似对象的方式进行访问。
       使用Dll提供接口只能是平面的,比如提供函数。但是COM可以让你获取对象指针(当然是COM对象)
       这样,对象的层次关系更为明显。
    3。这是一个相对通用的二进制标准。插件开发者不需要先熟悉不同的特定的规范标准(当然要依照COM规范)。COM的弊端
    1。需要换一种方式思考问题。
       一般情况下,我们写代码都习惯于谁创建,谁释放。但是使用COM,通常你创建了就不由你释放了。对象
       之间的有效性及同步问题比较麻烦。
    2。多线程序的控制比较麻烦。
       按一些书上的说明叫做线程套间。我没仔细看,但是感觉上比直接使用Dll的函数进行线程同步要麻烦很多。
    3。对程序员的要求相对较高。
       COM开发对开发人员的水平,以及对开发人员对COM机制的熟悉程度要求比较高。要想开发一个比较稳定的
       COM插件相对来讲比使用DLL的函数更复杂一些。这是我的一些体会。