unit demo;interface
uses StrUtils,Dialogs;
type
  TYD=class(TObject)
  public
    x1:Integer;
    procedure aa();
    function aa1():String;  private
    m1:Integer;
    procedure bb();  published
    constructor Create();
  end;implementation
constructor TYD.Create();
begin
  //
end;
procedure TYD.aa();
begin
  ShowMessage('xxx');
end;
function TYD.aa1():String;
begin
  result:='100';
end;
procedure TYD.bb();
begin
  //
end;
end.上面的类如何让他导出?   导出之后在另一程序中如何使用该类??   高手指点指点!!

解决方案 »

  1.   

    看了半天资料,整到这个地步整不下去了,运行报内存错误:大家看看错在哪里???
    一、dll代码:
    library Project1;uses
      ComServ,
      demo in 'demo.pas',
      demo_Intf in 'demo_Intf.pas';var
      x:Integer;
      yd:TYD;
    exports
      DllGetClassObject,
      DllCanUnloadNow,
      DllRegisterServer,
      DllUnregisterServer,init;
    {$R *.RES}begin
    end.--------------------------------------------------------------------------
    unit demo_Intf;interface
    type
      TYDBase=class(TObject)
      public
        x1:Integer;
        procedure aa();virtual;abstract;
        function aa1():String;virtual;abstract;
        
      private
        m1:Integer;  end;
    implementationend.
    ------------------------------------------------------------------------------------
    unit demo;interface
    uses StrUtils,Dialogs,demo_Intf;
    type
      TYD=class(TYDBase)
      public
        x1:Integer;
        procedure aa();override;
        function aa1():String;override;
        
      private
        m1:Integer;  published
        constructor Create();
      end;
      
    function init():TYD;stdcall;implementation
    constructor TYD.Create();
    begin
      //
    end;
    procedure TYD.aa();
    begin
      ShowMessage('xxx');
    end;
    function TYD.aa1():String;
    begin
      result:='100';
    end;
    function init():TYD;
    begin
      result:=TYD.Create;
    end;
    end.二、调用工程代码
    procedure TForm1.Button1Click(Sender: TObject);
    var
      dllHandle:   THandle;
      yd:TYDBase;
    begin
      yd:=Init;
      yd.aa;
      {
       dllHandle := LoadLibrary('Project1.DLL'); //动态载入DLL,并返回其句柄
        try
          if dllHandle <> 0 then //如果载入成功则获取SplitString函数的地址
            yd:= GetProcAddress(dllHandle, 'yd');
          if not (@yd = nil) then
          begin
            yd.aa;
            //ShowMessage(PChar(yd1.aa1));
            //yd1.x1:=70;
            //ShowMessage(IntToStr(yd1.x1));
          end;
        finally
          FreeLibrary(dllHandle); //调用完毕收回DLL占用的资源
        end;
        }
    end;
    -----------------------------------------------------------------------
    unit demo_Intf;interface
    type
      TYDBase=class(TObject)
      public
        x1:Integer;
        procedure aa();virtual;abstract;
        function aa1():String;virtual;abstract;
        
      private
        m1:Integer;  end;
      function Init:TYDBase;external   'Project1.dll.dll';implementationend.
      

  2.   

    总体来说,很晕。
    上面有两处代码打错了,但是纠正之后运行仍然报内存错,就是不知道怎么调用对象里的东西的。.....
    1.dll的project1中多了var x,yd
    2.'Project1.dll.dll';   多.dll
      

  3.   

    dll用使用对像是不可以的,但可以使用接口定义一个接口文件
    Ia = interface
     {guid ctrl+shift+c}
      procedure xxx; stdcall;
    end;dll 和调用者都引用这个接口文件dll中大概如下TA = class(TInterfacedObject, Ia)
    protected
      { Ia}
      procedrue xxx; stdcall; 实现这个
    end;function exportA: Ia; stdcall;
    begin
      result := TA.Crate as Ia;
    end;调用者这边不要释放 Ia,由记数去完成你的代码的想法是没错的 demo_Intf 中定义的是抽像类, interface 实质上就是一个抽像类. 这里改改应该就可以了
      

  4.   

    说明一下为什么不可以, 类函数在 dll 中的位置是相对的,只有在 load 进入后才确定一个绝对位置
    dll & exe 都引用了 demo_intf, RTTI是存在于 dll 和 exe 中的, 分别独立, exe里并不知道 TYDBase这个类在dll 中的派生类存在, 多态就不能被使用, 换句话说这时你不能由dll建立由exe愁释放,入口是不同的,必须由建立一一方完成释放才行,这样只有 interface 才能实现了, 不用interface的代码就是当时能用,也不能保证之后的运行是稳定的
      

  5.   

    同意楼上,用Interface实现
    1.创建COM+及接口函数
    2.调用对象时用COM+的接口函数调用Dll
      

  6.   

    不知道说的对不对,不对请指教~
    ---------------------------------------------
    Dll中封装对象一般是这样的
    1.Dll中的对象实例只能在dll中创建
    2.应用程序只能调用动态绑定的方法
    3.对于Dll中对象的释放
    对于为什么只能调用动态方法,很明显,不把方法声明为虚方法,对象的方法就进不去VMT表,VMT中就不会有方法的入口地址,否则,应用程序即使得到了对象的地址,也得不到相应的方法。
    所以一般大家都用抽象类或接口来实现DLL对类的封装。
    如果用接口的话,可以利用实例计数器来自动管理对象的生命期,从而达到对象释放的目的。我在项目中创建了一个ObjectBroker的COM+,用COM+来调用DLL