如何把一个datamodule做成DLL,可以在几个应用程序里调用?(代码) 如题 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我的想法是把一个工程分成N个模块,都做成DLL,然后再做一个DATAMODULE的DLL让这N个模块共享 注意dll的共享机制和Delphi的包技术的共享机制不同;推荐用Delphi的包技术,进行大的功能模块的划分;CommonDM:数据连接的共享;肯定整个程序的连接只有一个;如果采用dll共享连接,难保一个程序只有一个连接,如果一个程序出现多个连接,那数据库的客户端的数量就会减少,可惨了;本来连100个没问题(保持最佳性能),但如果一个程序占用5个(你有五个模块),那数据库只能带20个客户端了;CommonDM,共享数据模版的方法,我通过sqlserver的监视器看到只有一个连接;unit CommonDM;interfaceuses SysUtils, Classes, DB, ADODB,IniFiles,Dialogs,Forms, TCarRentINI;type TCommonDataModule = class(TDataModule) procedure DataModuleCreate(Sender: TObject); private { Private declarations } public { Public declarations } function GetSystemDateTime():TDateTime; end;var CommonDataModule: TCommonDataModule; CarRentConn: TADOConnection; UserID:integer; //用户编号 DepartmentID : string; //公司部门编号 RoleID : string; //角色编号 { 个人:只能查看自己的信息 部门:只能查看本部门的信息 公司:查看全部的公司信息 }implementation{$R *.dfm}procedure TCommonDataModule.DataModuleCreate(Sender: TObject);var ConnStr:string; ini : CarRentINI;begin //ini := CarRentINI.Create('E:\易通软件功能文档\源代码\Config\CarRent.ini','cadserver'); ini := CarRentINI.Create(ExtractFileDir(application.exeName)+'\CarRent.ini','cadserver'); try try ConnStr := 'Provider='+ini.ReadString('connect','Provider','')+ ';Persist Security Info='+ini.ReadString('connect','Persist Security Info','')+ ';User ID='+ini.ReadString('connect','User ID','')+ ';Password='+ini.ReadString('connect','Password','')+ ';Initial Catalog='+ini.ReadString('connect','Initial Catalog','')+ ';Data Source='+ini.ReadString('connect','Data Source',''); if CarRentConn = nil then begin CarRentConn := TADOConnection.Create(application); CarRentConn.LoginPrompt:= false; CarRentConn.ConnectionString := ConnStr; end; finally ini.Free; end; except ShowMessage('数据库初始化连接失败'); end;end;function TCommonDataModule.GetSystemDateTime: TDateTime;var tempQr:TADoQuery;begin tempQr:=TAdoQuery.Create(nil); try tempQr.Connection:=CarRentConn; tempQr.Close(); tempQr.SQL.Clear(); tempQr.SQL.Add('select GetDate()'); tempQr.Prepared; tempQr.Open(); Result:=tempQr.Fields[0].Value; Finally tempQr.Free(); endend;initialization RegisterClass(TCommonDataModule);finalization UnRegisterClass(TCommonDataModule);end.********************************************************************其他分功能的模块引用CommonDM,模块内部要建立ADOConnnection的连接实例;要在主模块里建立实例;********************************************************************在主模块的DM里Create事件里unit CarRentDM;interfaceuses SysUtils, Classes, DB, ADODB,Forms,CommonDM;type TCarRentDataModule = class(TDataModule) procedure DataModuleCreate(Sender: TObject); procedure DataModuleDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end;var CarRentDataModule: TCarRentDataModule;implementation{$R *.dfm}var //myCommonDM:TCommonDataModule; DMpk:HMODULE; h:TPersistentClass;procedure TCarRentDataModule.DataModuleCreate(Sender: TObject);begin //////////////公用数据库连接//////////////////// DMpk:=LoadPackage('CommonPk.bpl'); h := GetClass('TCommonDataModule'); CommonDataModule:=TCommonDataModule(TComponentClass(h).Create(Application)); //发布时考虑删除 //ADOConnection1 := CarRentConn; //AdoConnection1.Open;end;procedure TCarRentDataModule.DataModuleDestroy(Sender: TObject);begin if DMpk<>0 then UnLoadPackage(DMpk);end;end.****************************CommonDM里的全局变量 CarRentConn 是个模块共享的连接; 应该现了解在delphi中dll的使用特性。及dll的应用机制。dll适用于开发大型工程时,分成若干个子工程时可以使用。如果只是用来编写类似的函数库。然后调用它。那么切记不要在该dll中使用vcl组件。也就是说一个主程序,一个dll文件。主程序不能控制dll文件中的vcl组件,dll文件也不能控制主程序中的vcl组件。只用将纯业务的程序封装在dll中是可以的照上面说的,您最好不要将datamodule封装成dll文件(您肯定会在里面用到数据库组件),然后主程序调用它。您最好写在包或组件里! 我是想把工程分模块来做,做N个DLL文件,但是和数据库的连接我又想用DATAMODULE来统一做,而不是在每个模块甚至每个窗体里放数据库组件,因为这样数据库组件其实有很多是重复的,所以我就想到了把一个DATAMODULE做成DLL. 我上面不是给你例子了吗但是,用的是包技术,很好用的,好好研究一下吧,用Delphi,最好用包来划分大的模块;不要围绕着dll转了,他有很多局限性;没有包更适合Delphi的了;我给你的例子,是数据模版上有一个adoconnection,他是全局共享的,当然你也可以在放一些其他的咚咚,或者功能函数等等;我一般这么设计有的程序 app | ------------------------------------ | | | | CommonDM(通用数据模板) | |--------|-------------------------| | | | 模块1 模块2 模块3 .....在app实例化CommonDM中的全局性的类,这样CommonDM的实例在整个程序中就只有一个应用了(单态);同时app实例化各个模块,而各个模块都用到了CommonDM中的单态类,他已经被app先期实例化了;这种结构要求模块的独立性要好(看你设计的水平了,如果设计的不好,出现单元在包中的重复引用是不允许的),这只是基本结构,看对你有没有帮助;个人意见,仅供参考;csdn要是能贴图就好了!!!!!!!!!!!! 和小齐同声呐喊,有图的CSDN将会更精彩! 还有,我想问一下哪本Delphi的书介绍包的知识比较多一点,我手头上的几本好象都没介绍到这个知识点。 delphi5开发人员指南,其中有介绍包的,但还是不多,我市通过摸索,和看了李维的关于包的介绍后,才有启发的;尤其是和接口一齐应用,那效果无以伦比,dll望尘莫及;个人观点:如果要用delphi,想到了用dll,那就应该放弃它,马上想到package,如果不会的朋友,真的应该学一学,不难的;到http://qixin000.vicp.net/down (一般在早8:00到22:00开放,如下不了,请等等再试)上面有个package.rar的文件,你可一下载,那时李维关于包的文章; to qixin000:sorry,我慢了一步,那个package.rar能否给我发一份,本人的E-MAIL:[email protected],谢谢! 菜鸟的调试问题 查询问题 EXP workflow 是那个公司出的工作流调度系统(顶者有分) 怎样实现数据的条件值,分区域的打印?好久都没能解决盼能人救我!!! 在线等待,怎么改变屏幕分辩率?? 怎么把Listview中的选择的多行,插入到另外一个listview中。 install shields 6.x哪里有下载???????? 还有爱分的高手吗?偶是牛虻,来帮偶呀!!!!!!!!!!! 这里的文章是不是应该再分些子类了? 如何得到报表的总页数? 如何调出打印设置对话框,可以选择打印页数和份数的那个。 我想作一个VOD软件(电脑点歌机)可是不太懂,大侠帮忙好吗?
推荐用Delphi的包技术,进行大的功能模块的划分;
CommonDM:数据连接的共享;肯定整个程序的连接只有一个;如果采用dll共享连接,
难保一个程序只有一个连接,如果一个程序出现多个连接,那数据库的客户端的数量就会
减少,可惨了;本来连100个没问题(保持最佳性能),但如果一个程序占用5个(你有五个模块),那数据库只能带20个客户端了;
CommonDM,共享数据模版的方法,我通过sqlserver的监视器看到只有一个连接;unit CommonDM;interfaceuses
SysUtils, Classes, DB, ADODB,IniFiles,Dialogs,Forms,
TCarRentINI;type
TCommonDataModule = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function GetSystemDateTime():TDateTime;
end;var
CommonDataModule: TCommonDataModule;
CarRentConn: TADOConnection; UserID:integer; //用户编号
DepartmentID : string; //公司部门编号
RoleID : string; //角色编号
{
个人:只能查看自己的信息
部门:只能查看本部门的信息
公司:查看全部的公司信息
}implementation{$R *.dfm}procedure TCommonDataModule.DataModuleCreate(Sender: TObject);
var
ConnStr:string;
ini : CarRentINI;
begin
//ini := CarRentINI.Create('E:\易通软件功能文档\源代码\Config\CarRent.ini','cadserver'); ini := CarRentINI.Create(ExtractFileDir(application.exeName)+'\CarRent.ini','cadserver');
try
try
ConnStr := 'Provider='+ini.ReadString('connect','Provider','')+
';Persist Security Info='+ini.ReadString('connect','Persist Security Info','')+
';User ID='+ini.ReadString('connect','User ID','')+
';Password='+ini.ReadString('connect','Password','')+
';Initial Catalog='+ini.ReadString('connect','Initial Catalog','')+
';Data Source='+ini.ReadString('connect','Data Source','');
if CarRentConn = nil then
begin
CarRentConn := TADOConnection.Create(application);
CarRentConn.LoginPrompt:= false;
CarRentConn.ConnectionString := ConnStr;
end;
finally
ini.Free;
end;
except
ShowMessage('数据库初始化连接失败');
end;
end;function TCommonDataModule.GetSystemDateTime: TDateTime;
var
tempQr:TADoQuery;
begin
tempQr:=TAdoQuery.Create(nil);
try
tempQr.Connection:=CarRentConn;
tempQr.Close();
tempQr.SQL.Clear();
tempQr.SQL.Add('select GetDate()');
tempQr.Prepared;
tempQr.Open();
Result:=tempQr.Fields[0].Value;
Finally
tempQr.Free();
end
end;initialization
RegisterClass(TCommonDataModule);finalization
UnRegisterClass(TCommonDataModule);end.
********************************************************************
其他分功能的模块引用CommonDM,模块内部要建立ADOConnnection的连接实例;
要在主模块里建立实例;
********************************************************************
在主模块的DM里Create事件里
unit CarRentDM;interfaceuses
SysUtils, Classes, DB, ADODB,Forms,CommonDM;type
TCarRentDataModule = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
CarRentDataModule: TCarRentDataModule;implementation{$R *.dfm}
var
//myCommonDM:TCommonDataModule;
DMpk:HMODULE;
h:TPersistentClass;procedure TCarRentDataModule.DataModuleCreate(Sender: TObject);
begin
//////////////公用数据库连接////////////////////
DMpk:=LoadPackage('CommonPk.bpl');
h := GetClass('TCommonDataModule');
CommonDataModule:=TCommonDataModule(TComponentClass(h).Create(Application)); //发布时考虑删除
//ADOConnection1 := CarRentConn;
//AdoConnection1.Open;
end;procedure TCarRentDataModule.DataModuleDestroy(Sender: TObject);
begin
if DMpk<>0 then UnLoadPackage(DMpk);
end;end.
****************************
CommonDM里的全局变量 CarRentConn 是个模块共享的连接;
及dll的应用机制。dll适用于开发大型工程时,分成若干个子工程时可以使用。
如果只是用来编写类似的函数库。然后调用它。
那么切记不要在该dll中使用vcl组件。
也就是说一个主程序,一个dll文件。
主程序不能控制dll文件中的vcl组件,
dll文件也不能控制主程序中的vcl组件。
只用将纯业务的程序封装在dll中是可以的
照上面说的,您最好不要将datamodule封装成dll文件(您肯定会在里面用到数据库组件),然后主程序调用它。您最好写在包或组件里!
但是,用的是包技术,很好用的,好好研究一下吧,用Delphi,最好用包来划分大的模块;
不要围绕着dll转了,他有很多局限性;没有包更适合Delphi的了;我给你的例子,是数据模版上有一个adoconnection,他是全局共享的,当然你也可以在放一些其他的咚咚,或者功能函数等等;我一般这么设计有的程序 app
|
------------------------------------
| | |
| CommonDM(通用数据模板) |
|--------|-------------------------|
| | |
模块1 模块2 模块3 .....在app实例化CommonDM中的全局性的类,这样CommonDM的实例在整个程序中就只有一个应用了(单态);同时app实例化各个模块,而各个模块都用到了CommonDM中的单态类,他已经被app
先期实例化了;这种结构要求模块的独立性要好(看你设计的水平了,如果设计的不好,出现单元在包中的重复引用是不允许的),这只是基本结构,看对你有没有帮助;个人意见,仅供参考;csdn要是能贴图就好了!!!!!!!!!!!!
个人观点:
如果要用delphi,想到了用dll,那就应该放弃它,马上想到package,如果不会的朋友,真的应该学一学,不难的;到http://qixin000.vicp.net/down (一般在早8:00到22:00开放,如下不了,请等等再试)
上面有个package.rar的文件,你可一下载,那时李维关于包的文章;
sorry,我慢了一步,那个package.rar能否给我发一份,本人的E-MAIL:[email protected],谢谢!