gpt4 book ai didi

c# - 使用/不使用 JCL 在 Delphi 中托管 CLR - 示例

转载 作者:IT王子 更新时间:2023-10-29 04:48:53 28 4
gpt4 key购买 nike

有人可以在这里发布一个如何在 Delphi 中托管 CLR 的示例吗?我读过类似的 question在这里,但我不能使用 JCL,因为我想在 Delphi 5 中托管它。谢谢。


编辑这个article关于在 Fox Pro 中托管 CLR 看起来很有希望,但我不知道如何从 Delphi 访问 clrhost.dll。


编辑 2: 我放弃了对 Delphi 5 的要求。现在我正在尝试使用 Delphi 7 的 JCL。但是我还是找不到任何示例。这是我到目前为止所拥有的:

我的 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: Variant does not reference an automation object

我已经很长时间没有使用 Delphi 了,所以我被困在这里......


解决方案:COM 可见性存在问题,默认情况下并非如此。这是正确的 .NET 程序集:

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

重要提示:

在 Delphi 中使用 .NET 时,重要的是在程序开始时调用 Set8087CW($133F);(即在 Application.Initialize; 之前)。 Delphi 默认启用浮点异常(参见 this),CLR 不喜欢它们。当我启用它们时,我的程序奇怪地卡住了。

最佳答案

这是另一种选择。

那是 C# 代码。即使您不想使用 my unmanaged exports ,它仍然会解释如何在不通过 IDispatch 的情况下使用 mscoree(CLR 托管的东西)(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 接口(interface)声明:

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.

当我改编 Lars 的样本时,它看起来像这样:

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.

在这种情况下,您当然可以从 C# 代码中删除“UnmanagedExports”类。

关于c# - 使用/不使用 JCL 在 Delphi 中托管 CLR - 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2048540/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com