是否可以将一些类放入DLL中?
我正在处理的项目中有几个自定义类,并希望将它们放入DLL中,然后在需要时在主应用程序中访问,如果它们在DLL中,我可以在其他项目中重用这些类如果我需要的话。
我发现这个链接:http://www.delphipages.com/forum/showthread.php?t=84394讨论了访问DLL中的类,它提到了委托给类型属性,但我在Delphi帮助或在线上找不到任何关于此的更多信息。
有什么理由我不应该把类放在DLL中,如果没有问题,那么在上面的链接示例中是否有更好的方法呢?
由于
答案 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这样的系统 - 或者坚持使用包裹。但它可以用另一种方式完成吗?当然可以。但是以时间和努力为代价。