{
单元文件列表:
接口单元:IuserInfo,其中定义一个接口 IuserInfoLib;
业务逻辑单元:UserInfoLib,其中定义业务逻辑类:TUserInfoLib,该类实现了接口IuserInfoLib
}
现在我的一个业务逻辑类封装到了Dll中,
接口单元IuserInfo的代码:unit IuserInfo;
interface
type
    IuserInfoLib=interface
        function GetUserInfo(AuserName:pchar):olevariant;overload;  //获取指定用户名的信息
        function GetUserInfo:olevariant;overload;                    //获取全部的用户信息
    end;
implementation
end.
业务逻辑单元UserInfoLib
unit UserInfoLib;interface
uses
    Windows,Messages, SysUtils, Variants, Classes,
    Graphics,ImgList,ComCtrls,
    sysDM,    //引用数据模块单元
    IUserInfo;  //引用接口单元
type
    TUserInfoLib=class(TInterfacedObject,IuserInfoLib)
    private
      UserDM:TDataModule1;  //数据模块
    public
      constructor create;
      destructor Destroy;override;      //下面这两个方法来自接口 IuserInfoLib
      function GetUserInfo(AuserName:pchar):olevariant;overload;  //获取指定用户名那个的用户信息
      function GetUserInfo:olevariant;overload;                   //获取全部的用户信息
    end;implementation
//构造方法
constructor TuserInfoLib.create;
begin
    userDM:=Tdatamodule1.Create(nil);
end;
//析构方法
Destructor TuserInfoLib.Destroy;
begin
    freeAndNil(UserDM);
    Inherited;
end;
//获取指定用户名的用户信息
function TuserInfoLib.GetUserInfo(AuserName:pchar):olevariant;
begin
    if not userDM.Adoconnection1.connected
       then  userDM.ADOconnection1.connected:=true;    with UserDM.AdoqUserInfo do
    begin
        close;
        sql.clear;
        sql.Add('select * from tb1 where userName=:tmpUserInfo');
        parameters.ParamByName('tmpUserInfo').Value:=string(AuserName);
        open;
    end;
    result:=UserDM.DspUserInfo.Data; //返回根据用户名的查询结果的数据集
end;//获取全部的用户信息
function TuserInfoLib.GetUserInfo:olevariant;
begin
    if not userDM.Adoconnection1.connected
       then  userDM.ADOconnection1.connected:=true;    with UserDM.AdoqUserInfo do
    begin
        close;
        sql.clear;
        sql.Add('select * from tb1');
        open;
    end;
    result:=UserDM.DspUserInfo.Data; //返回根据用户名的查询结果的数据集
end;
DLL工程单元
library UserInfoDLL;uses
  SysUtils,
  Classes,
  sysDM in 'sysDM.pas' {DataModule1: TDataModule},
  IuserInfo in 'IuserInfo.pas',
  UserInfoLib in 'UserInfoLib.pas';{$R *.res}function CreateUserInfoLib:IuserInfoLib; //返回接口
begin
    TUserInfoLib.create; //创建类的实例
end;exports
    CreateUserInfoLib;   //导出函数----------------------------在主程序中调用dll。unit mainform;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, DBGrids, DB, DBClient,
  IuserInfo, StdCtrls;type
  TmyFunction=function:IuserInfoLib;  //声明一个函数类型  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);    procedure Button1Click(Sender: TObject);
  private
    UserLib:TmyFunction; //函数类型
    myHandle:Thandle;    //dll句柄
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}//窗体载入
procedure TForm1.FormCreate(Sender: TObject);
begin
    myHandle:=LoadLibrary('UserInfoDLL.dll');         //载入DLL
    @UserLib:=GetProcAddress(myHandle,'GetUserInfo');   //获取到DLL中的函数
end;//窗体销毁
procedure TForm1.FormDestroy(Sender: TObject);
begin
   UserLib:=nil;
   freeLibrary(myHandle); //释放
end;
//点击获取全部用户信息
procedure TForm1.Button1Click(Sender: TObject);
begin
    if UserLib<>nil then
       clientDataset1.Data:=UserLib.GetUserInfo; //系统报告AV错误这里!!!
end;上面代码只是测试 演示下,没有考虑吧其他的异常等情况。
clientDataset1.Data:=UserLib.GetUserInfo;  请大家看看问题出在什么地方??
谢谢

解决方案 »

  1.   

    function CreateUserInfoLib:IuserInfoLib; //返回接口
    begin
        TUserInfoLib.create; //创建类的实例
    end;
    这里没有返回.
      

  2.   

    function CreateUserInfoLib:IuserInfoLib; //返回接口
    begin
        TUserInfoLib.create; //创建类的实例
    end;沒有返回
      

  3.   


    改了
      result:=TUserInfoLib.create;还是一样。这里我确实是忘记写了,但还是AV错误
      

  4.   


    这个是忘记了,刚才加上了result:=。。还是有错误工程代码在这里:http://download.csdn.net/source/1157618僵哥和starluck 有时间帮看看,小弟感激不尽。
    刚学Delphi 的OOP
      

  5.   

    DspUserInfo.Data是不是接口类型?在使用时是不是直接调用其中的方法?有没有对返回值进行检查?接口交互的时候,比如返回值会不会存在非接口的类(包括Class,String,array等)?可以先试试在DLL和主程序都加上ShareMem单元到工程的最前面(uses中排在第一个)
      

  6.   

        @UserLib:=GetProcAddress(myHandle,'GetUserInfo');//获取到DLL中的函数DLL里面的函数名叫什么?
      

  7.   

    DspUserInfo.Data是不是接口类型?不是吧,DspUserInfo 是datasetprovider。
    Datasetprovider在DM中相关联的是adoquery1,也就是代码中AdoqUserInfoadoquUserInfo执行查询后将数据集通过DspUserInfo传递到前端的clientDataset
      

  8.   

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        myHandle:=LoadLibrary('UserInfoDLL.dll'); //载入DLL
        //@UserLib:=GetProcAddress(myHandle,'GetUserInfo');//获取到DLL中的函数    @UserLib:=GetProcAddress(myHandle,'CreateUserInfoLib');//改掉
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
        //if UserLib<>nil then
        if Assigned(UserLib) then//改掉
           clientDataset1.Data:=UserLib.GetUserInfo; //获取全部的用户信息
    end;
    function CreateUserInfoLib:IuserInfoLib; //返回接口
    begin
       //TUserInfoLib.create; //创建类的实例
       Result := TUserInfoLib.create; //改掉
    end;
      

  9.   

    1.DLL当中没有返回值,先改掉并编译
    2.DLL导出的函数名是'CreateUserInfoLib',而调用程序当中用的是'GetUserInfo',要改掉
    3.判断函数不能直接x<>Nil,而使用Assigned(X),改掉做完上面的就OK了。
      

  10.   


    嘿嘿。
    疏忽了,已经改正,Okay自己懵了,谢谢僵哥和starLuck!!