Hosting CLR in Delphi with/without JCL - example

前端 未结 5 692
渐次进展
渐次进展 2020-11-27 13:13

Can somebody please post here an example how to host CLR in Delphi? I have read similar question here but I cannot use JCL as I want to host it in Delphi 5. Thank you.

5条回答
  •  渐次进展
    2020-11-27 13:26

    Here's another option.

    That's the C# Code. And even if you do not want to use my unmanaged exports, it would still explain how to use mscoree (the CLR hosting stuff) without going through IDispatch (IDispatch is pretty slow).

    using System;
    using System.Collections.Generic;
    using System.Text;
    using RGiesecke.DllExport;
    using System.Runtime.InteropServices;
    
    namespace DelphiNET
    {
    
       [ComVisible(true)]
       [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
       [Guid("ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31")]
       public interface IDotNetAdder
       {
          int Add3(int left);
       }
    
       [ComVisible(true)]
       [ClassInterface(ClassInterfaceType.None)]
       public class DotNetAdder : DelphiNET.IDotNetAdder
       {
          public int Add3(int left)
          {
             return left + 3;
          }
       }
    
       internal static class UnmanagedExports
       {
          [DllExport("createdotnetadder", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
          static void CreateDotNetAdderInstance([MarshalAs(UnmanagedType.Interface)]out IDotNetAdder instance)
          {
             instance = new DotNetAdder();
          }
       }
    }
    

    This is the Delphi interface declaration:

    type
      IDotNetAdder = interface
      ['{ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31}']
        function Add3(left : Integer) : Integer; safecall;
      end;
    

    If you use unmanaged exports, you can do it like so:

    procedure CreateDotNetAdder(out instance :  IDotNetAdder); stdcall;
      external 'DelphiNET' name 'createdotnetadder';
    
    var
      adder : IDotNetAdder;
    begin
      try
       CreateDotNetAdder(adder);
       Writeln('4 + 3 = ', adder.Add3(4));
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    

    When I adapt Lars' sample, it would look like so:

    var
      Host: TJclClrHost;
      Obj: IDotNetAdder;
    begin
      try
        Host := TJclClrHost.Create;
        Host.Start();
        WriteLn('CLRVersion = ' + Host.CorVersion);
    
        Obj := Host.DefaultAppDomain
                   .CreateInstance('DelphiNET', 
                                   'DelphiNET.DotNetAdder')
                   .UnWrap() as IDotNetAdder;
        WriteLn('2 + 3 = ', Obj.Add3(2));
    
        Host.Stop();
      except
        on E: Exception do
          Writeln(E.Classname, ': ', E.Message);
      end;
    end.
    

    In this case you could remove the "UnmanagedExports" class from the C# code, of course.

提交回复
热议问题