请教高手,如何用动态连接库(DLL)封装对象(包括属性)300分 ( 积分: 300 )

  • 主题发起人 主题发起人 hwxie
  • 开始时间 开始时间
H

hwxie

Unregistered / Unconfirmed
GUEST, unregistred user!
如这个类如何使用DLL封装:
  TGraphics = class
private
FSelected: Boolean;
FMoving: Boolean;
FResizing: Boolean;
procedure SetSelected(Value: Boolean);
protected
property Moving: Boolean read FMoving write FMoving;
property Resizing: Boolean read FResizing write FResizing;
public
function PointInside(APoint: TPoint): Boolean
virtual
abstract;
function PointInResizeControl(APoint: TPoint): Boolean
virtual
abstract;
function GetResizeCursor(APoint: TPoint): TCursor
virtual
abstract;
procedure Paint(ACanvas: TCanvas)
virtual
abstract;
procedure Select
virtual;
procedure UnSelect
virtual;
procedure Move(ACanvas: TCanvas
offsetX, offsetY: Integer)
virtual
abstract;
procedure ReSize(ACanvas: TCanvas
CurPoint: TPoint)
virtual
abstract;
property Selected: Boolean read FSelected write SetSelected;
end;
 
如这个类如何使用DLL封装:
  TGraphics = class
private
FSelected: Boolean;
FMoving: Boolean;
FResizing: Boolean;
procedure SetSelected(Value: Boolean);
protected
property Moving: Boolean read FMoving write FMoving;
property Resizing: Boolean read FResizing write FResizing;
public
function PointInside(APoint: TPoint): Boolean
virtual
abstract;
function PointInResizeControl(APoint: TPoint): Boolean
virtual
abstract;
function GetResizeCursor(APoint: TPoint): TCursor
virtual
abstract;
procedure Paint(ACanvas: TCanvas)
virtual
abstract;
procedure Select
virtual;
procedure UnSelect
virtual;
procedure Move(ACanvas: TCanvas
offsetX, offsetY: Integer)
virtual
abstract;
procedure ReSize(ACanvas: TCanvas
CurPoint: TPoint)
virtual
abstract;
property Selected: Boolean read FSelected write SetSelected;
end;
 
使用接口的方式将类的public部分引出
 
首先谢谢您的帮助。我已经试过了,但不成功。
可以给个例子吗?只要封装一个简单的类,不要有窗体。
 
如果你只是使用导出的类(不涉及到在Dll外的继承),可以直接接口或者直接导出类本身,如果涉及到继承,可以考虑使用Delphi的包
 
无需DLL外继承,只要DLL内继承就好了。
 
接口声明单元,需要在Dll和EXE中都引用这个单元
unit Unit2;
interface
uses
Controls, Types, Graphics;
type
IGraphics = Interface(IInterface)
['{B6F5DF58-128A-4760-8D15-966A05F2C765}']
procedure SetSelected(Value: Boolean);
function GetSelected: Boolean;
function PointInside(APoint: TPoint): Boolean;
function PointInResizeControl(APoint: TPoint): Boolean;
function GetResizeCursor(APoint: TPoint): TCursor;
procedure Paint(ACanvas: TCanvas);
procedure Select;
procedure UnSelect;
procedure Move(ACanvas: TCanvas
offsetX, offsetY: Integer);
procedure ReSize(ACanvas: TCanvas
CurPoint: TPoint);
property Selected: Boolean read GetSelected write SetSelected;
end;
implementation
end.
 
DLL中的接口实现单元(照抄你原来的)
在DLL中导出
function CreateGraphics: IGraphics;
函数

unit Unit1;

interface

uses
Controls, Types, Graphics, Unit2;

type
TGraphics = class(TObject, IGraphics)
private
FSelected: Boolean;
FMoving: Boolean;
FResizing: Boolean;
procedure SetSelected(Value: Boolean);
function GetSelected: Boolean;
protected
function QueryInterface(const IID: TGUID
out Obj): HResult
stdcall;
function _AddRef: Integer
stdcall;
function _Release: Integer
stdcall;

property Moving: Boolean read FMoving write FMoving;
property Resizing: Boolean read FResizing write FResizing;
public
function PointInside(APoint: TPoint): Boolean
virtual
abstract;
function PointInResizeControl(APoint: TPoint): Boolean
virtual
abstract;
function GetResizeCursor(APoint: TPoint): TCursor
virtual
abstract;
procedure Paint(ACanvas: TCanvas)
virtual
abstract;
procedure Select
virtual;
procedure UnSelect
virtual;
procedure Move(ACanvas: TCanvas
offsetX, offsetY: Integer)
virtual
abstract;
procedure ReSize(ACanvas: TCanvas
CurPoint: TPoint)
virtual
abstract;
property Selected: Boolean read GetSelected write SetSelected;
end;

function CreateGraphics: IGraphics;

implementation

function CreateGraphics: IGraphics;
begin
Result := TGraphics.Create();
end;

{ TGraphics }

function TGraphics.GetSelected: Boolean;
begin
.....
end;

function TGraphics.QueryInterface(const IID: TGUID
out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;

procedure TGraphics.Select;
begin
......
end;

procedure TGraphics.SetSelected(Value: Boolean);
begin
......
end;

procedure TGraphics.UnSelect;
begin
.....
end;

function TGraphics._AddRef: Integer;
begin
Result := -1;
end;

function TGraphics._Release: Integer;
begin
Result := -1;
end;

end.
 
这种方式不方便的地方是,在DLL和引用DLL的EXE的工程文件中需要把ShareMem放在第一个引用的位置,例如在DLL中

library Project1;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
ShareMem,
SysUtils,
Classes,
Unit1 in 'Unit1.pas',
Unit2 in 'Unit2.pas';

{$R *.res}
 
不用接口的话要用到Class of
如 TGraphics = class;
TGraphicsClass = class of TGraphics ;
再将类的定义放在一个公用单元中 DLL里面才能传出来,否则就用接口或是BPL方式
 
我是想使用DLL来封装类,以保护实现的代码。你的例子中将实现部分都写在DLL外了。
我的邮箱Hwxie@gct.com.cn;
可以发例子给我吗?万分感谢!
 
放飞你有邮箱吗?我发代码给你,你看能否实现封装吧?好妈?
 
放飞你不要放我飞机啊![:(]
 
w_xieyang@tom.com
 
创建一个包,其中包含GraphicsClassUnit和VectorGraphClassUnit单元,然后在你的程序中带包运行。
这是最简单的方式
如果使用接口,那么,你需要创建一个接口单元,将TVectorGraph和TGraphics声明成接口。这种方式修改的地方很多,代价比较大
 
上面给你的例子就是将TGraphics声明成接口。
Unit1是DLL中的单元,用来实现隐藏实现部分的目的。
Unit2是公共单元,DLL和EXE中都需要引用,这个单元仅仅是一个声明
在EXE中,TGraphics类型的变量用IGraphics接口类型替换
 
包是指Package吗?这样不能实现隐藏实现部分的目的吧?
 
可以实现。
包是特殊的DLL
想隐藏实现部分你只需要不向其提供源代码而只提供编译后的bpl或者dcu
 
感谢放飞的帮助。谢谢你。
meigreat:谢谢你的参与。
meigreat:50;
放飞:250
 
后退
顶部