在 Delphi 中使用/不使用 JCL 托管 CLR - 示例
有人可以在这里发布一个如何在 Delphi 中托管 CLR 的示例吗?我在这里读过类似的 问题,但我不能将 JCL 用作我想在 Delphi 5 中托管它。谢谢。
编辑:这篇关于托管 CLR 的文章在 Fox Pro 中看起来很有希望,但我不知道如何从 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 没有引用自动化对象
我已经很长时间没有使用 Delphi,所以我被困在这里...
<强>解决方案: COM 可见性存在问题,默认情况下并非如此。这是正确的 .NET 程序集:
namespace DelphiNET
{
[ComVisible(true)]
public class NETAdder
{
public int Add3(int left)
{
return left + 3;
}
}
}
重要提示:
在 Delphi 中使用 .NET 时,在程序开头(即在 Application.初始化;
)。 Delphi 默认情况下启用了浮点异常(请参阅此),并且 CLR 没有不喜欢他们。当我启用它们时,我的程序奇怪地冻结了。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是另一种选择。
这就是 C# 代码。即使您不想使用我的非托管导出,它也会仍然
解释如何使用 mscoree(CLR 托管工具)而不通过 IDispatch(IDispatch 非常慢)。
这是 Delphi 接口声明:
如果您使用非托管导出,您可以这样做:
当我改编 Lars 的示例时,它看起来像这样:
在这种情况下,您可以从 C# 代码中删除“UnmanagementExports”类,课程。
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).
This is the Delphi interface declaration:
If you use unmanaged exports, you can do it like so:
When I adapt Lars' sample, it would look like so:
In this case you could remove the "UnmanagedExports" class from the C# code, of course.
类必须是可见的。如果整个程序集有 ComVisible(false) ,情况可能并非如此。
.Net 类默认情况下将与 IDispatch 兼容,因此如果该类确实是可见的,您的示例应该可以正常工作。
但首先将其精简到最低限度。将您的 exe 放在与 .Net 程序集相同的文件夹中,并跳过配置文件和应用程序库。
在事情变得混乱之前,这里就发生了异常,对吗?
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?
在这里:
注意:假设 DelphiNET.NETAdder 类型和 DelphiNet.dll 中的 Add3 方法是 ComVisible。感谢罗伯特。
更新:
使用反射时,不需要 ComVisible 属性。下一个示例甚至可以在不使用 ComVisible 的情况下工作。
Here you go:
Note: Assumes that the DelphiNET.NETAdder type and the Add3 method in DelphiNet.dll is ComVisible. Thanks to Robert.
Update:
When using reflection you do not need the ComVisible attribute. Next example even works without being ComVisible.
我在使用“TJclClrHost”组件时遇到了一些麻烦(参见 src 代码中的注释)。经过搜索后,我发现了“CppHostCLR”Microsoft 示例,它是新的接口路径,以便在 Win32/64 应用程序中托管 .NET 运行时...
这是用 Delphi 编写的快速(且肮脏)示例版本(也可在此处获取) :http://chapsandchips.com/Download/DelphiNETHost_v1.zip)
仅Delphi接口(与“OleVariant”/后期绑定)在此示例代码中实现。
呵呵,问候。
帕斯卡
I faced some troubles with "TJclClrHost" component (cf. comments in src code). After searching around, i found-out "CppHostCLR" Microsoft sample which is the new interfaced path in order to host .NET runtime in Win32/64 application...
Here's a quick (and dirty) sample version written with Delphi (also available here : http://chapsandchips.com/Download/DelphiNETHost_v1.zip)
Only Delphi interfacing (with "OleVariant" / late binding) is implemented in this sample code.
hth, regards.
Pascal
感谢这个论坛,我找到了将 dll C# 与 Lazarus 一起使用的最佳解决方案:
C#:
Lazarus:
观察 var Z 是 WideString,唯一可以用作字符串类型的类型,我尝试了 String、AnsiString 和 PChar 但没有工作,它们仅返回第一个字符。
我遇到了重音问题,比如将“Antônio”作为参数发送,我试图找到一个 C# 可以理解并发回相同单词的转换器。
Thanks this forum I find out the best solution to use dll C# with Lazarus:
C#:
Lazarus:
Observe that var Z is WideString, the only type that worked as string type, I tried String, AnsiString and PChar but didnt work, they return only the first char.
Im having problem with accent like the word "Antônio" to send as parameter, Im trying to find a converter that the C# can understand and send back the same word.