把类放在DLL中?

时间:2012-10-18 12:43:55

标签: delphi class dll delphi-xe

是否可以将一些类放入DLL中?

我正在处理的项目中有几个自定义类,并希望将它们放入DLL中,然后在需要时在主应用程序中访问,如果它们在DLL中,我可以在其他项目中重用这些类如果我需要的话。

我发现这个链接:http://www.delphipages.com/forum/showthread.php?t=84394讨论了访问DLL中的类,它提到了委托给类型属性,但我在Delphi帮助或在线上找不到任何关于此的更多信息。

有什么理由我不应该把类放在DLL中,如果没有问题,那么在上面的链接示例中是否有更好的方法呢?

由于

4 个答案:

答案 0 :(得分:14)

无法从DLL获取类/实例。 您可以将接口移交给类,而不是类。 下面是一个简单的例子

// The Interface-Deklaration for Main and DLL
unit StringFunctions_IntfU;

interface

type
  IStringFunctions = interface
    ['{240B567B-E619-48E4-8CDA-F6A722F44A71}']
    function CopyStr( const AStr : WideString; Index, Count : Integer ) : WideString;
  end;

implementation

end.

简单的DLL

library StringFunctions;

uses
  StringFunctions_IntfU; // use Interface-Deklaration

{$R *.res}

type
  TStringFunctions = class( TInterfacedObject, IStringFunctions )
  protected
    function CopyStr( const AStr : WideString; Index : Integer; Count : Integer ) : WideString;
  end;

  { TStringFunctions }

function TStringFunctions.CopyStr( const AStr : WideString; Index, Count : Integer ) : WideString;
begin
  Result := Copy( AStr, Index, Count );
end;

function GetStringFunctions : IStringFunctions; stdcall; export;
begin
  Result := TStringFunctions.Create;
end;

exports
  GetStringFunctions;

begin
end.

现在简单的主程序

uses
  StringFunctions_IntfU;  // use Interface-Deklaration

// Static link to external function
function GetStringFunctions : IStringFunctions; stdcall; external 'StringFunctions.dll' name 'GetStringFunctions';

procedure TMainView.Button1Click( Sender : TObject );
begin
  Label1.Caption := GetStringFunctions.CopyStr( Edit1.Text, 1, 5 );
end;

答案 1 :(得分:5)

为此目的使用运行时包;这正是他们首先设计的。它们会自动加载(或者可以手动加载),并自动设置相同内存管理器的共享,以便您可以在它们之间自由使用类和类型。

使用软件包要好得多(由于这个原因,这正是IDE为其大部分功能所做的工作)。

答案 2 :(得分:3)

Delphi不支持从DLL导入或导出类。要从其他模块导入类,您需要使用包。

答案 3 :(得分:2)

虽然官方的答案是“你不能”,但当然一切皆有可能。像Remobjects SDK和Remobjects Hydra这样的框架已经做了很长时间了。问题是它需要你围绕这样一个系统创建一个基础设施,这不是Delphi开箱即用的。

第一步是内存管理。 DLL被加载到加载它的进程中,但它不共享内存管理。它必须是这种方式,因为DLL可以用无数种语言创建,每种语言都有自己的内部机制。这带来了安全问题(即程序写入DLL内存,反之亦然)。

其次,界面(阅读:内容描述)。您的应用程序将如何知道它可以创建的类,类成员,参数类型等。这就是COM需要类型库的原因,它描述了DLL的内容。

第三,终身管理。如果DLL处理从DLL创建的对象的内存管理,则DLL也必须释放所述对象。

以上步骤已经存在,它被称为COM。您当然可以随意创建尽可能多的COM DLL文件,只需记住在使用它们之前必须在Windows中注册这些文件。您的应用程序“在运行中”(如果您有安全权限)或安装人员。 这就是为什么COM代表最终的插件系统,很少被Delphi程序员使用,因为使用它作为插件系统的技术成本超过了它的好处。

替代方式

如果您可以确保您的DLL仅供Delphi程序使用,那么您还有第二种方法可供探索。您必须创建方法来与DLL共享主程序的内存管理器(Remobjects这样做)。这允许您在DLL和主应用程序之间共享对象,字符串等。

然后,您可以使用RTTI“映射”存储在DLL中的类(DLL必须执行此操作并生成类和方法表),这些类可以通过您自己设备的代理类调用。

总而言之,除非你有足够的空闲时间浪费,否则我会购买像Remobjects Hydra这样的系统 - 或者坚持使用包裹。但它可以用另一种方式完成吗?当然可以。但是以时间和努力为代价。