在dll中能不能声明一些类,供外部程序调用?能给个例子最好;

mayma 2003-09-12 11:23:50
由于程序中有很多需要公用的类,加上现在要将一些程序独立,这样调用这些公用类的地方就多了,我想把这些类写成dll,不知道该怎么做?写完后delphi程序怎么调用?谢谢了!
以下是两个需要写的例子:
TParmsBD = record
...................
................
end;

TRunlist=class(TBaseRunlist)
.........
.........
end;
...全文
72 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
tonylk 2003-09-12
  • 打赏
  • 举报
回复
忘了说明了,要让主程序和dll之间能够正常的传递类,需要使用sharemem,或是runtime bpl,我比较喜欢后者.
Delphi_Li 2003-09-12
  • 打赏
  • 举报
回复
你好好看看Delphi 5开发人员指南这本书关于DLL的介绍,上面有一个完整的例子。(这本书是中文的!!!)
bluenightsky 2003-09-12
  • 打赏
  • 举报
回复
学习
tonylk 2003-09-12
  • 打赏
  • 举报
回复
我就打放血一次吧,也许有点复杂,你仔仔细细的看吧,另外,我用dll导出的是类,(返回类型是class of class),而不时传统意义上的具体对象,因为这样可以通过同一个接口返回各种不同类型的类实现,更灵活一点,有点像com的class factory.

主程序:
======
PCompCardItem = ^TCompCardItem;
TCompCardItem = record
DllHandle:Hwnd;
FileName:String;
CardGUID:TGUID;
CardName:String;
GetCompEditor:GetCompEditorProc;
GetCompController:GetCompControllerProc;
GetCompLoader:GetCompLoaderProc;
end;

//将某个dll中的内容信息保存在队列内
procedure TCompCardManager.AddCompCard(AFileName:String);
var
Item:PCompCardItem;
DllHandle:Hwnd;
GetCardGUID:GetCardGUIDProc;
GetCardName:GetCardNameProc;
FileName:String;
begin
FileName:=ExtractFileName(AFileName);
if Assigned(FOnLoading) then begin
FOnLoading(self,Format('Loading %s...',[FileName]),300);
end;
DllHandle:=LoadLibrary(PChar(AFileName));
if DllHandle<>0 then begin
GetCardGUID:=GetProcAddress(DllHandle,'GetCardGUID');
GetCardName:=GetProcAddress(DllHandle,'GetCardName');
if (@GetCardGUID<>nil) and (@GetCardName<>nil) then begin
new(Item);
Item^.DllHandle:=DllHandle;
Item^.FileName:=AFileName;
Item^.CardGUID:=GetCardGUID();
Item^.CardName:=GetCardName();
Item^.GetCompEditor:=GetProcAddress(DllHandle,'GetCompEditor');
Item^.GetCompController:=GetProcAddress(DllHandle,'GetCompController');
Item^.GetCompLoader:=GetProcAddress(DllHandle,'GetCompLoader');
FCompCardList.Add(Item);
end
else begin
FreeLibrary(DllHandle);
raise CompCardException.CreateFmt('Card "%s" is not a valid card file!',[FileName]);
end;
end
else begin
raise CompCardException.CreateFmt('Can not load card "%s"!',[FileName]);
end;
end;

//从已存在的Dll列表中找到要找的那个,并且调用其中的函数,让其返回某个类(是类不是对象)
function TCompCardManager.FindCompLoader(ACardGUID:TGUID):TCompLoaderClass;
var
Item:PCompCardItem;
I:Integer;
begin
Result:=nil;
for I:=0 to FCompCardList.Count-1 do begin
Item:=FCompCardList.Items[I];
if IsEqualGUID(Item^.CardGUID,ACardGUID) then begin
if Assigned(Item^.GetCompLoader) then begin
Result:=Item^.GetCompLoader();
end;
exit;
end;
end;
end;

//程序最终通过该找到的类来创建出真正的对象。
procedure TRoundManager.LoadCompetition(ATypeGUID:String;AFileName:String;ARoundID:Integer);
var
CompLoaderClass:TCompLoaderClass;
CompLoader:TCompLoader;
begin
CompLoaderClass:=GCardManager.FindCompLoader(StringToGUID(ATypeGUID));
if not Assigned(CompLoaderClass) then begin
raise RoundMgrException.Create('Can not found CompLoaderClass!');
end;
CompLoader:=CompLoaderClass.Create();
if not Assigned(CompLoader) then begin
raise RoundMgrException.Create('Can not create CompLoader!');
end;
CompLoader.LoadCompetition(AFileName,ARoundID,FDataStream);
end;

dll中:
======
function GetCompLoader():TCompLoaderClass;
begin
Result:=TBasketballLoader;
end;

exports
GetCompLoader;

//TCompLoader的具体实现
type
TBasketballLoader = class(TCompLoader)
public
procedure LoadCompetition(AFileName:String;ARoundID:Integer;ADataStream:TMemoryStream);override;
end;

//主程序和dll都共有的基类声明,这样主程序才能知道到底哪些方法是该类所支持的。
type
TCompLoaderClass = class of TCompLoader;

TCompLoader = class(TObject)
public
procedure LoadCompetition(AFileName:String;ARoundID:Integer;ADataStream:TMemoryStream);virtual;abstract;
end;


tonyki@citiz.net
www.tonixsoft.com
mayma 2003-09-12
  • 打赏
  • 举报
回复
怎么没人回答?555555555555555~

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧