Хостинг CLR в Delphi с/без JCL - пример

Кто-то может отправить здесь пример, как разместить CLR в Delphi? Я считал подобный вопрос здесь, но я не могу использовать JCL, поскольку я хочу разместить его в Delphi 5.Спасибо.


Править: Эта статья о хостинге CLR в Fox Pro выглядит многообещающей, но я не знаю, как получить доступ к clrhost.dll от Delphi.


Редактирование 2: Я разочаровываюсь в требовании Delphi 5. Теперь я пробую JCL Delphi 7. Но снова я не могу найти любой пример. Вот то, что я имею до настоящего времени:

Мой блок C#:

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

Я скомпилировал его в DelphiNET.dll.

Теперь я хочу использовать этот блок от 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;

Это заканчивается ошибкой: EOleError: Вариант не ссылается на объект автоматизации

Я не работал с Delphi в течение долгого времени, таким образом, я застреваю здесь...


Решение: была проблема в видимости COM, которая не является по умолчанию. Это - корректный блок.NET:

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

Важное примечание:

При работе с.NET от Delphi это - важный вызов Set8087CW($133F); в начале Вашей программы (т.е. прежде Application.Initialize;). Delphi включил исключения в операции с плавающей запятой по умолчанию (см. это), и CLR не нравятся они. Когда мне включили их, моя программа, странно замороженная.

18
задан Community 23 May 2017 в 12:09
поделиться

3 ответа

Класс должен быть уверен в себе. Что может быть не так, если вы увидите (ложь) для всей сборки.

.NET Classes будет совместимым iDispatch по умолчанию, поэтому ваш образец должен работать совсем хорошо, если класс действительно невидим ..

, но внизу его до минимума. Поместите свой EXE в той же папке, что и узел .NET и пропустить файл конфигурации и прикладную базу.

До чего-то смешивается, исключение раскало здесь, верно?

 ov := obj.Unwrap;
8
ответ дан 30 November 2019 в 08:27
поделиться

Вот еще один вариант.

Это код C #. И даже если вы не хотите использовать мой неуправляемый экспорт , это все равно Объясните, как использовать MSCOREEE (проведение хостинга CLR), не проходя через Idispatch (IDispatch довольно медленно).

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();
      }
   }
}

Это декларация интерфейса Delphi:

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

Если вы используете неуправляемый экспорт, вы можете сделать это так:

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.

, когда я адаптировать образец Ларса, это будет выглядеть так:

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.

в этом случае вы могли бы Удалите класс «UnmanedExports» из кода C #, конечно.

12
ответ дан 30 November 2019 в 08:27
поделиться

Здесь вы идете:

program CallDotNetFromDelphiWin32;

{$APPTYPE CONSOLE}

uses
  Variants, JclDotNet, mscorlib_TLB, SysUtils;

var
  Host: TJclClrHost;
  Obj: OleVariant;
begin
  try
    Host := TJclClrHost.Create;
    Host.Start;
    WriteLn('CLRVersion = ' + Host.CorVersion);

    Obj := Host.DefaultAppDomain.CreateInstance('DelphiNET', 'DelphiNET.NETAdder').UnWrap;
    WriteLn('2 + 3 = ' + IntToStr(Obj.Add3(2)));

    Host.Stop;
  except
    on E: Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

Примечание: предполагает, что тип delphinet.netdder и метод ADD3 в delphinet.dll - это . Благодаря Роберт .

Обновление :

При использовании отражения вам не нужен неизбежный атрибут. Следующий пример даже работает, не будучи невидимым.

Assm := Host.DefaultAppDomain.Load_2('NetAddr');
T := Assm.GetType_2('DelphiNET.NETAdder');
Obj := T.InvokeMember_3('ctor', BindingFlags_CreateInstance, nil, null, nil);
Params := VarArrayOf([2]);
WriteLn('2 + 3 = ' + IntToStr(T.InvokeMember_3('Add3', BindingFlags_InvokeMethod, nil, Obj, PSafeArray(VarArrayAsPSafeArray(Params)))));
6
ответ дан 30 November 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: