在Delphi程序中托管.NET运行时

13

我正在研究如何在Delphi程序中使用一些.NET代码,我需要使用.NET程序集和预定义函数使我的程序可扩展(我已经支持常规DLL)。

在网上搜索了很多后,我发现了Managed-VCL,但我还不愿意为我所需的内容支付250美元,我也找到了一些新闻组中的代码,但这些代码不完整并且无法工作。

我正在使用Delphi 2007 for win32。我可以使用什么来动态执行具有预定义参数的程序集功能?

像这样:

procedure ExecAssembly(AssemblyFileName:String; Parameters: Variant);

我想强调的是,我需要能够加载任意程序集(可能是特定文件夹中的所有程序集),因此创建C#包装器可能行不通。

7个回答

7

自己托管CLR并不是很难(特别是如果您只使用单个AppDomain)。您可以使用基于COM的托管API启动运行时,在装配件中加载程序集,创建对象并调用它们上的方法。

有很多在线信息,例如MSDN关于“托管公共语言运行时”的文档。(新位置)


我遇到了一个问题:Could not load file or assembly 'RGiesecke.DllExport.Metadata, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ad5f9f4a55b5020b' or one of its dependencies. The system cannot find the file specified. 我使用这个包是因为它有 [DllExport] 注释。问题在这里 - dialex

7
在Jedi Code Library(JCL)中 - 免费的 - 有一个名为JclDotNet.pas的文件,其中包含一个名为TJclClrHost的类,可能可以实现您想要的功能。
  TJclClrHost = class(TJclClrBase, ICorRuntimeHost)
  private
    FDefaultInterface: ICorRuntimeHost;
    FAppDomains: TObjectList;
    procedure EnumAppDomains;
    function GetAppDomain(const Idx: Integer): TJclClrAppDomain;
    function GetAppDomainCount: Integer;
    function GetDefaultAppDomain: IJclClrAppDomain;
    function GetCurrentAppDomain: IJclClrAppDomain;
  protected
    function AddAppDomain(const AppDomain: TJclClrAppDomain): Integer;
    function RemoveAppDomain(const AppDomain: TJclClrAppDomain): Integer; 
  public
    constructor Create(const ClrVer: WideString = '';
      const Flavor: TJclClrHostFlavor = hfWorkStation;
      const ConcurrentGC: Boolean = True;
      const LoaderFlags: TJclClrHostLoaderFlags = [hlOptSingleDomain]);
    destructor Destroy; override;
    procedure Start;
    procedure Stop;
    procedure Refresh;
    function CreateDomainSetup: TJclClrAppDomainSetup;
    function CreateAppDomain(const Name: WideString;
      const Setup: TJclClrAppDomainSetup = nil;
      const Evidence: IJclClrEvidence = nil): TJclClrAppDomain;
    function FindAppDomain(const Intf: IJclClrAppDomain; var Ret: TJclClrAppDomain): Boolean; overload;
    function FindAppDomain(const Name: WideString; var Ret: TJclClrAppDomain): Boolean; overload;
    class function CorSystemDirectory: WideString;
    class function CorVersion: WideString;
    class function CorRequiredVersion: WideString;
    class procedure GetClrVersions(VersionNames: TWideStrings); overload;
    class procedure GetClrVersions(VersionNames: TStrings); overload;
    property DefaultInterface: ICorRuntimeHost read FDefaultInterface implements ICorRuntimeHost;
    property AppDomains[const Idx: Integer]: TJclClrAppDomain read GetAppDomain; default;
    property AppDomainCount: Integer read GetAppDomainCount;
    property DefaultAppDomain: IJclClrAppDomain read GetDefaultAppDomain;
    property CurrentAppDomain: IJclClrAppDomain read GetCurrentAppDomain;
  end;

4
我瞎了还是这里没有使用示例? - Lukas Cenovsky

6
我可以从第一手经验告诉您,使用Delphi与.Net进行互操作并不容易。我是一位.Net开发人员,但曾在一家.Net和Delphi的公司工作过一段时间。 我管理了几个项目,这些项目是用.Net(WinForms和WPF)编写的,但由Delphi调用。我们的Delphi团队已经为Delphi编写了一个Interop层,以便调用.Net库,因为我们所有的新产品都是用.Net编写的。对于我们来说(即使这些都是优秀的Delphi开发人员),这是一个麻烦。如果我们能够购买一个好的第三方库来为我们做Interop,那将是非常值得的。我敢打赌,我们在处理Delphi到.Net的Interop时花费了数千美元的人力和物力。
我建议您试用Managed-VLC库,看看它的表现如何。如果它能够达到其广告效果,那么它轻松地就值得250美元。

4

请参见我的问题,其中提供了使用JCL在Delphi中托管CLR的端到端示例。


3

我曾经遇到过同样的问题。我在一家 Delphi 店工作,他们想要开始向遗留的 Delphi 应用程序添加 .NET 和 C# 的功能。我看了看 Managed-VLC,但决定跳过它,因为我觉得它存在一些严重的问题。我在这里找到了一个更简单的东西:Delphi.NET。注意:这不是原生运行在 .NET 上的 Delphi 版本。这是一个开源项目,通过 COM 和反射允许遗留的 Delphi 应用程序访问 .NET 功能。虽然它有点老,但由于使用了 COM,所以它非常好用。我可以证实它可以与 .NET 2.0 和 3.5 兼容。我花了几天时间将 .NET DLL 完全集成到我们的遗留 Delphi 5 应用程序中。我的老板认为我是个超级英雄。祝你好运!


2

您可以在Delphi中将.Net类作为COM对象使用:

  • 使用C#创建程序集
  • 为程序集创建类型库
  • 在Delphi中导入类型库

现在,您可以访问在类型库中导出的.Net程序集中的类。


2

你可以使用 Delphi for .Net 和非托管导出,也称为反向 P/Invoke。

这基本上让您创建一个具有完全访问 .Net 框架的 .Net .dll,但可以像任何 .dll 一样被任何本地语言加载,而无需 com 互操作的开销。

这是一个简单的示例: http://cc.codegear.com/Item/22688


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接