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

Posted

技术标签:

【中文标题】在 Delphi 程序中托管 .NET 运行时【英文标题】:Hosting the .NET runtime in a Delphi Program 【发布时间】:2010-09-20 12:11:10 【问题描述】:

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

在网上大量搜索后,我找到了Managed-VCL,但我还没准备好花 250 美元购买我需要的东西,我还发现一些新闻组的代码不完整且无法正常工作。

我将 Delphi 2007 用于 win32。我可以使用什么来从具有预定义参数的程序集中动态执行函数?

类似:

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

我只想补充一点,我需要能够加载任意程序集(可能是特定文件夹中的所有程序集),因此创建 C# 包装器可能不起作用。

【问题讨论】:

【参考方案1】:

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

【讨论】:

我是瞎还是没有例子怎么用?【参考方案2】:

自己托管 CLR 并不是那么困难(尤其是在您只使用单个 AppDomain 时)。您可以使用基于 COM 的托管 API 来启动运行时、加载程序集、创建对象并在其上调用方法。

网上有很多信息,例如“Hosting the Common Language Runtime”上的 MSDN 文档。 (new home)

【讨论】:

我得到一个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] 注释,我正在使用该包。问题here【参考方案3】:

我可以从第一手经验告诉您,与 Delphi 的 .Net 进行互操作绝非易事。我是 .Net 人,但曾在 .Net 和 Delphi 商店工作过一段时间。我管理了几个用 .Net(WinForms 和 WPF)编写但被 Delphi 调用的项目。我们的 Delphi 人员已经为 Delphi 编写了一个互操作层来调用 .Net 库,因为我们所有的新产品都是用 .Net 编写的。这对我们来说很麻烦(这些都是优秀的 Delphi 开发人员)。如果我们可以购买 good 第三方库来为我们进行互操作,那将是非常值得的。我敢打赌,我们花费了数千美元的工时编写和调试从 Delphi 到 .Net 的互操作问题。

我会将该 Managed-VLC 库用于试驾,看看它的工作情况如何。如果它不辜负它的广告,那么它很容易值 250 美元。

【讨论】:

【参考方案4】:

有关在 Delphi 中使用 JCL 托管 CLR 的端到端示例,请参阅 my question。

【讨论】:

【参考方案5】:

我遇到了同样的问题。我在一家 Delphi 商店工作,他们想开始使用 .NET 和 C# 向旧版 Delphi 应用程序添加功能。我查看了 Managed-VLC 并决定跳过它,因为我觉得它有一些严重的问题。我在这里发现了一些更简单的东西:Delphi.NET。注意:这不是在 .NET 上本机运行的 Delphi 版本。这是一个开源项目,允许旧版 Delphi 应用程序通过 COM 和反射访问 .NET 功能。尽管它很旧,但由于它使用 COM,它就像一个魅力。我将验证它是否适用于 .NET 2.0 和 3.5。几天之内,我就将 .NET DLL 完全集成到了我们的旧版 Delphi 5 应用程序中。我的老板认为我是超级英雄。祝你好运!

【讨论】:

【参考方案6】:

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

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

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

【讨论】:

【参考方案7】:

您可以将 Delphi 用于 .Net 和非托管导出,也称为反向 P/Invoke。

这实际上让您可以创建一个 .Net .dll,它可以完全访问 .Net 框架,但可以由任何本地语言加载,就像使用任何 .dll 一样,并且没有 com 互操作的开销。

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

【讨论】:

以上是关于在 Delphi 程序中托管 .NET 运行时的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 中运行 .Net 1.1 应用程序时出错

用户运行托管 IIS 链接时如何在 asp.net 中获取客户端 IP 地址

net框架运行原理

Oracle ODP.NET 托管驱动程序在 64 位中的运行速度比在 32 位中慢 50-100%

将解决方案发布到文件夹时出错 - 自托管 .NET

托管C++C++/CLICLR