Search code examples
c#.netdelphiclrhost

Hosting CLR in Delphi with/without JCL - example


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.


EDIT: This article about hosting CLR in Fox Pro looks promising but I don't know how to access clrhost.dll from Delphi.


Edit 2: I give up on Delphi 5 requirement. Now I'm trying JCL with Delphi 7. But again I am unable to find any example. Here is what I have till now:

My C# assembly:

namespace DelphiNET
{
    public class NETAdder
    {
        public int Add3(int left)
        {
            return left + 3;
        }
    }
}

I have compiled it to DelphiNET.dll.

Now I want to use this assembly from Delphi:

uses JclDotNet, mscorlib_TLB;

procedure TForm1.Button1Click(Sender: TObject);
var
  clr: TJclClrHost;
  ads: TJclClrAppDomainSetup;
  ad: TJclClrAppDomain;
  ass: TJclClrAssembly;
  obj: _ObjectHandle;
  ov: OleVariant;
begin
  clr := TJclClrHost.Create();
  clr.Start;
  ads := clr.CreateDomainSetup;
  ads.ApplicationBase := 'C:\Delhi.NET';
  ads.ConfigurationFile := 'C:\Delhi.NET\my.config';
  ad := clr.CreateAppDomain('myNET', ads);
  obj := (ad as _AppDomain).CreateInstanceFrom('DelphiNET.dll', 'DelphiNET.NETAdder');
  ov := obj.Unwrap;
  Button1.Caption := 'done ' + string(ov.Add3(5));
end;

This ends with error: EOleError: Variant does not reference an automation object

I have not worked with Delphi for a long time so I am stuck here...


Solution: There was problem in COM visibility which is not by default. This is the correct .NET assembly:

namespace DelphiNET
{
    [ComVisible(true)]
    public class NETAdder
    {
        public int Add3(int left)
        {
            return left + 3;
        }
    }
}

Important note:

When working with .NET from Delphi, it is important calling Set8087CW($133F); at the beginning of your program (i.e. before Application.Initialize;). Delphi has enabled floating point exceptions by default (see this) and the CLR doesn’t like them. When I had them enabled, my program weirdly freezed.


Solution

  • The class has to be comvisible. Which might not be the case if you have ComVisible(false) for the whole assembly.

    .Net classes will be IDispatch compatible by default, so your sample should work just fine, if the class really is comvisible..

    But strip it down to the bare minimum first. Put your exe in the same folder as your .Net assembly and skip the config file and application base.

    Before something gets mixed up, the exception happesn here, right?

     ov := obj.Unwrap;