新文章 网摘 文章 随笔 日记

使用JVCL的Delphi和.NET Interop

Delphi与.NET Framework通信的方法有多种:

  • 商业项目,例如Remobjects Hydra,Atozed CrossTalk和Managed VCL等。
  • 使用导入组件向导导入.NET程序集。
  • 或使用JVCL的开源方法。

为什么要选择JVCL而不是商业项目和Delphi的Import Component Wizard?

  • 开源,例如像啤酒一样免费。
  • 独立于regasm.exe,后者将类库注册到全局程序集缓存(GAC)中

JclDotNet如何工作?

通过为.NET类库提供基于变体的
后期绑定自动化,JVCL使用JclDotNet单元提供了与.NET Framework的通信

This post will provide two examples by stepping through each part, which should provide a basic grounding on how the 
JVCL JclDotNet unit communicates with .NET Framework.

For these examples your Delphi must have JVCL 3.45 or higher installed and for  the C# Class Library .NET 4.5 Framework
 (Visual Studio 2012).

例子1

本示例通过调用C#类库Example1ClassLibrary.DLL演示两个数字的基本加法。

Delphi示例
  • 要启动TJclClrHost类,必须初始化.NET Framework –公共语言运行时(CLR)并启动主机:
1 Host := TJclClrHost.Create('v4.0.30319');
2 Host.Start();
  • 注意:默认情况下,如果将ClrVer变量保留为空白,则默认为v2.0.50727
1 Host := TJclClrHost.Create;
  • 对于此示例,我们将使用支持.NET 4.5或.NET 4 Framework的CLR v4.0.30319。
  • 现在必须初始化C#类库,并且必须初始化Obj:OleVariant才能访问方法:
1 Obj := Host.DefaultAppDomain
2 .CreateInstance('Example1ClassLibrary' {.NET Assemble Name},
3  
4 'Example1ClassLibrary.Example1' {Namespace.Classname})
5  
6 .UnWrap();
  • 第一部分是.NET汇编文件' Example1ClassLibrary .dll'的名称。
  • “ Example1ClassLibrary.Example1 ”的下一部分是名称空间和类名
  • 从C#类库简单地访问此方法,就可以使名称和参数与类库相同:
1 Result := Obj.AddFunction(aXValue, aYValue);
  • 释放CLR主机只是停止并释放TJclClrHost类:
1 Host.Stop();
2 Host.Free;
全功能
1 function TfrmMain.AddFunction(aXValue: Integer; aYValue:Integer): Integer;
2 var
3   Host: TJclClrHost;
4   Obj: OleVariant;
5 begin
6   try
7     Host := TJclClrHost.Create('v4.0.30319');
8     Host.Start();
9  
10     Obj := Host.DefaultAppDomain
11         .CreateInstance('Example1ClassLibrary',
12         'Example1ClassLibrary.Example1')
13         .UnWrap();
14  
15      Result := Obj.AddFunction(aXValue, aYValue);
16  
17     Host.Stop();
18     Host.Free;
19   Except
20      on E : Exception do
21      begin
22        ShowMessage('Exception class name = '+E.ClassName + ' ' + 'Exception message = '+E.Message);
23      end;
24   end;
25 end;

C#类库

示例1类库的一些基本设置允许Delphi与Interop Services一起工作:

  • 包括在Interop Services的名称空间中
1 using System.Runtime.InteropServices;
  • 将类公开给COM访问Delphi
1 [ComVisible(true)]
2 public class Example1
  • 所有功能必须公开
1 public int AddFunction(int aXValue, int aYValue)
2 {
3 return aXValue + aYValue;
4 }
类库
1 namespace Example1ClassLibrary
2 {
3     [ComVisible(true)]
4     public class Example1
5     {
6         public int AddFunction(int aXValue, int aYValue)
7         {
8             return aXValue + aYValue;
9         }
10     }
11 }

例子2

在此示例中,我们将两个数字基本加在一起,并扩展了Delphi如何使用mscorlib_TLB导入库访问Example2ClassLibrary.DLL:

Delphi示例
1 uses
2 mscorlib_TLB, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
3 Dialogs,? StdCtrls, JclDotNet;
  • 注意:mscorlib_TLB应该是第一个单元。
  • 在formcreate事件中将主机初始化为.NET Framework:
1 procedure TfrmMain.FormCreate(Sender: TObject);
2 begin
3    FClrHost := TJclClrHost.Create('v4.0.30319');
4  
5    FClrHost.Start;
6 end;
  • 设置对类库路径和应用程序的访问:
1 Fads.ApplicationBase := '..\Example2\Debug\Win32\';
2 Fad := FClrHost.CreateAppDomain('myNET', Fads);
  • 注意:如果要调用两个或多个,则CreateAppDomain('myNET'应该是一个不同的名称。
  • 现在必须初始化C#类库,并必须使用Obj:OleVariant来访问该方法:
1 obj := (Fad as _AppDomain).CreateInstanceFrom('Example2ClassLibrary.dll',
2      'Example2ClassLibrary.Example2');
3 ov := obj.Unwrap;result := ov.AddFunction(aXValue, aYValue);
  • 要释放CLR主机,只需停止并在FormDestory事件中设置免费即可:
1 procedure TfrmMain.FormDestroy(Sender: TObject);
2 begin
3   FClrHost.Stop();
4   FClrHost.Free;
5 end;
全功能
1 function TfrmMain.AddFunction(aXValue: Integer; aYValue:Integer): Integer;
2 var
3   Fads: TJclClrAppDomainSetup;
4   Fad: TJclClrAppDomain;
5   Ov: OleVariant;
6   obj: _ObjectHandle;
7 begin
8   try
9     Fads := FClrhost.CreateDomainSetup;
10  
11     Fads.ApplicationBase := '..\Example2\Debug\Win32\';
12     Fad := FClrHost.CreateAppDomain('myNET', Fads);
13     obj := (Fad as _AppDomain).CreateInstanceFrom('Example2ClassLibrary.dll',
14          'Example2ClassLibrary.Example2');
15     ov := obj.Unwrap;
16     result := ov.AddFunction(aXValue, aYValue);
17   except
18     on E : Exception do
19      begin
20        ShowMessage('Exception class name = '+E.ClassName +
21           ' ' + 'Exception message = '+E.Message);     end;
22   end;
23 end;

下载范例

https://github.com/acj1971/DelphiDotNETInteropJVCLExamples

链接

JVCL
http://jvcl.delphi-jedi.org/

.NET 4.5框架
http://www.microsoft.com/zh-cn/download/details.aspx?id=30653

通用语言运行时(CLR)
http://msdn.microsoft.com/zh-cn/library/8bs2ecf4.aspx

Remobjects九头蛇
http://www.remobjects.com/hydra/

Atozed CrossTalk
http://www.atozed.com/CrossTalk/index.en.aspx

托管VCL
http://www.managed-vcl.com/

导入组件向导
http://docwiki.embarcadero.com/RADStudio/XE3/en/Import_Component_Wizard

https://adamjohnston.me/delphi-dotnet-interop-with-jvcl/
posted @ 2021-03-12 11:06  岭南春  阅读(615)  评论(0)    收藏  举报