本文介绍了使用来自delphi的com-invisible .net程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境:Win7,Delphi 2010

Environment: Win7, Delphi 2010

我有带有所需类和接口的.NET程序集.

I have .NET assembly with needed classes and interfaces.

我看到该程序集已与gacutils.exe一起安装.

I see the assembly is installed with gacutils.exe.

 Interop.CNHVoyager2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5162c9617d11c099, processorArchitecture=x86

主要问题是程序集不提供COM接口.

the main problem is the assembly does not provide COM-interface.

是否可以从Delphi中访问程序集中的类和接口?

Is it possible to get access to classes and interfaces inside the assembly from Delphi?

我这样做:

procedure TCardReader.InitDotNetAssemblyLibrary;
var
  card: ICNHV2Card;
  hr: HRESULT;
  NetClassName: WideString;
begin
  NetClassName := 'CNHVoyager2.CNHV2Card, Interop.CNHVoyager2, Version=1.0.0.0,     Culture=neutral, PublicKeyToken=5162c9617d11c099, processorArchitecture=x86';
  hr := ClrCreateManagedInstance(PWideChar(NetClassName), StringToGUID('{155EF4F5-AA34-   4FF4-8EEA-DC4223DF139C}'), card);
  OleCheck(hr);
end;

我收到一条消息:

Class is not registered.

.NET dll在项目的文件夹中,并且是从该位置注册的.

The .NET dll is in the project's folder and is registered from the location.

有可能吗?

更新:正如David所说,我已经检查了现有的包装器.我发现Item从其中导出了TLB文件,现在可以在其中查看内容:

UPDATE: As David said I have checked the existing wrapper. And I found Item exported TLB file from it and see inside of it now:

 _foDevice = interface(IDispatch)
   ['{E21BD447-D9D6-4E40-9A5E-244AEC7CE979}']
   function ReadFileDirect(const oDriver: IfoFODD; const sFolder: WideString; 
                           const sFilename: WideString): IfoSummary; safecall;
 end;

所以我可以读取所需的数据文件.但是我需要IfoFODD驱动程序接口来执行此操作.在TLB中我看不到它.而且我认为它在.NET not-com-assembly内部,它本质上是驱动程序.我可以做一些像拆卸这样的界面吗?还是使用它的另一种(正确)方法?

So I can read needed data file. But I need IfoFODD driver interface to do it. In the TLB I can not see it. And I think it is inside the .NET not-com-assembly which is the driver by nature. Can I make some like disassemble to take the interface? Or is it another (correct) way to use it?

推荐答案

您可以通过编写适配器来解决此问题.创建一个C#程序集,将要使用的程序集用作参考.在COM可见类中包装所需的类.然后,Delphi代码可以使用您的COM适配器.

You can solve this problem by writing an adapter. Create a C# assembly that uses the assembly you wish to consume as a reference. Wrap up the classes that you need in COM visible classes. The Delphi code can then consume your COM adapter.

另一个选择是调整程序集并公开经典的本机DLL接口.您可以使用C ++/CLI混合模式来做到这一点.或使用Robert Gieseke的UnmanagedExports.COM包装器可能更干净,更易于编写代码.

Another option is to adapt the assembly and expose an classic native DLL interface. You can do that with C++/CLI mixed mode. Or with Robert Gieseke's UnmanagedExports. A COM wrapper is probably cleaner and easier to code against.

您可以按照尝试的方式进行操作.尽管您使用的接口已弃用.托管是这些天要做的事情.但是,正确的做法确实很棘手.它涉及大量的锅炉板.您将不得不完成COM所提供的免费腿部工作.我真的不推荐那条路线.用COM进行包装,使生活变得简单.

You can do it the way you are attempting. Although you are using a deprecated interface. Hosting is how it is meant to be done these days. However, it's really tricky to get right. It involves masses of boiler plate. You'll have to do loads of leg work that you'd get for free with COM. I really would not recommend that route. Wrap it up with COM and keep life simple.

这篇关于使用来自delphi的com-invisible .net程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 19:46