7

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

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

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

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

谢谢

4

4 回答 4

16

无法从 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;
于 2012-10-18T17:00:46.043 回答
5

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

使用包会更好(这正是 IDE 出于这个原因为其大部分功能所做的事情)。

于 2012-10-18T12:47:18.927 回答
3

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

于 2012-10-18T12:45:25.593 回答
3

虽然官方的回答是“你不能”,但当然一切皆有可能。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 这样的系统 - 要么坚持使用软件包。但它可以用另一种方式完成吗?当然可以。但是以时间和努力为代价。

于 2015-01-20T09:16:16.033 回答