0
votes

Environment: Win7, Delphi 2010

I have .NET assembly with needed classes and interfaces.

I see the assembly is installed with gacutils.exe.

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

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

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

I try so:

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;

And I get a message:

Class is not registered.

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

Is it possible at all?

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;

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?

1
Expose the functionality through COM. If the .net code does not already expose a COM interface, add that capability.David Heffernan
The problem is I have no access to the source code of the DLL. It is third party DLL. Is it possible to solve the task without COM-interface?mad
You don't need the source of the DLL. You just need to put an adapter between the DLL and your code.David Heffernan

1 Answers

2
votes

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.

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.

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.