Delphi 将类放入DLL?

Delphi 将类放入DLL?,delphi,class,dll,delphi-xe,Delphi,Class,Dll,Delphi Xe,是否可以将某些类放入DLL中 我在一个项目中有几个自定义类,我希望将它们放在一个DLL中,然后在需要时在主应用程序中访问,另外,如果它们在DLL中,如果需要,我可以在其他项目中重用这些类 我找到了这个链接:它讨论了访问DLL中的类,它提到了委托给类类型属性,但我在Delphi帮助或联机中找不到关于这个的任何进一步信息 有什么理由我不应该把类放在DLL中吗?如果可以的话,有没有更好的方法来实现这一点 谢谢Delphi不支持从DLL导入或导出类。要从另一个模块导入类,您需要使用包。为此使用运行时包;

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

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

我找到了这个链接:它讨论了访问DLL中的类,它提到了委托给类类型属性,但我在Delphi帮助或联机中找不到关于这个的任何进一步信息

有什么理由我不应该把类放在DLL中吗?如果可以的话,有没有更好的方法来实现这一点


谢谢

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

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


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

从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;

虽然官方的答案是“你不能”,但任何事情都是可能的。Remobjects SDK和Remobjects Hydra这样的框架已经做了很长时间了。问题是,它需要您围绕这样一个系统创建一个基础设施,而这不是Delphi现成的处理方法

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

第二,界面(读:内容描述)。应用程序如何知道它可以创建哪些类、类成员、参数类型等等。这就是COM需要类型库的原因,类型库描述DLL的内容

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

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

替代方法

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

然后,您可以使用RTTI“映射”DLL中存储的类(DLL必须这样做并生成类和方法表),这些类可以通过您自己设置的代理类调用


总之,除非你有足够的空闲时间去浪费,否则我要么买一个像Remobjects Hydra这样的系统,要么坚持使用软件包。但可以用另一种方式吗?当然可以。但这是以时间和努力为代价的。

您确实无法导入在Delphi的DLL中定义的类。除了所有需要克服的障碍,即使你可以,也没有语言支持。不能在类内使用
外部
。Delphi类没有
\uu declspec(dllimport)
。@David:这个问题从来没有问过导入,我也没有提到导出。这个问题问的是“将一些类放入DLL”,这实际上是可能的,并且可以从应用程序中使用它们(这同样需要大量的额外工作)。导入和导出是齐头并进的。从应用程序中使用它们意味着从DLL导出并导入到应用程序中。我相信你知道这一切。关键是,当代码位于DLL中时,实际上既不可能导出也不可能导入。对此没有Delphi语言支持。不能在exports语句中包含方法,也不能对方法使用
external
。所以你的中间段落在事实上是不准确的。@David:唯一“事实上不准确”的是“你可以做同样的事情”中的措辞错误,应该是“你可以使用DLL”。我会解决这个问题,因为它们显然不是“同一件事”。谢谢。@David:我同意。我找不到支持它的链接,因此我将从我的答案中删除该部分。如果我以后找到一个,我将回滚到预编辑版本并包含它。谢谢。虽然这确实是在DLL中调用代码的一种可行方法,但它实际上并没有回答这个问题。这是“有可能把一些类放到DLL中吗?”@David Heffernan如果你把它简化成这个问题,那么你是完全正确的,答案是:不可能。如果我是你,我会编辑你的答案。就在上面一句话。接下来的答案,概述了解决实际问题的好方法,仍然是很好的。StackOverflow是如何工作的。您回答了所问的问题,这就是为什么我没有将接口作为解决方案的原因。:-)回答得很好,但它需要先解决这个问题。@Ken好的,我知道,运行时软件包符合“是否可以将一些类放入DLL?”的问题以及对c语言的接口访问