views:

1852

answers:

10

I was looking into using some .NET code from within a Delphi program, I will need to make my program extensible using .net assemblies and predefined functions (I already support regular DLLs).

After a lot of searching online, I found Managed-VCL, but I'm not ready to pay $250 for what I need, I also found some newsgroups with code that's incomplete and doesn't work.

I'm using Delphi 2007 for win32. What can I use to dynamically execute a function from an assembly with predefined parameters?

Something like:

procedure ExecAssembly(AssemblyFileName:String; Parameters: Variant);

I just want to add that I need to be able to load an arbitrary assemblies (maybe all the assemblies in a specific folder), so creating a C# wrapper may not work.

+1  A: 

You can use .Net classes as COM objects in Delphi:

  • create assembly in C#
  • create type library for assembly
  • import type library in Delphi

Now you can access classes from .Net assembly that are exported in type library.

zendar
+5  A: 

I can tell you from first hand experience that inter-operating with .Net from Delphi is no picnic. I am a .Net guy, but worked in a .Net and Delphi shop for a while. I managed several projects that were written in .Net (WinForms and WPF) but were called by Delphi. Our Delphi guys had written an interop layer for Delphi to call out to .Net libraries since all of our new products were being written in .Net. It was trouble for us (and these were good Delphi developers). If we could have purchased a good 3rd party library to do the interop for us, it would have been more than worth it. I bet we spent thousands of dollars in man-hours writing and debugging problems with the interop from Delphi to .Net.

I would take that Managed-VLC library for a test drive to see how well it works. If it lives up to its advertising, then it is easily worth the $250.

Jason Jackson
+6  A: 

Hosting the CLR yourself is not all that difficult (especially if you are just using a single AppDomain). You can use the COM based hosting APIs to start up the runtime, load assemblies, create objects and invoke methods on them.

There is a lot of info online, for example the MSDN documentation on "Hosting the Common Language Runtime".

Rob Walker
+2  A: 

I had this exact same problem. I worked in a Delphi shop and they wanted to start adding functionality to a legacy Delphi app with .NET and C#. I looked at Managed-VLC and I decided to skip it, as I felt it had some serious problems. I found something much simpler here: Delphi.NET. Note: this is not the version of Delphi that runs natively on .NET. This is an open source project to allow legacy Delphi apps to access .NET functionality via COM and reflection. Even though it is old, it works like a charm since it uses COM. I'll verify that it works with .NET 2.0 and 3.5. I got .NET DLL's fully integrated into our legacy Delphi 5 application in days. My boss thought I was a superhero. Good luck!

postfuturist
+1  A: 

Also look into Hydra at RemObjects. With the recent adoption of their .net language engine by Embarcadero, I would expect them to be around and available for support for awhile.

skamradt
A: 

You could use Delphi for .Net and unmanaged exports, also called reverse P/Invoke.

This essentially lets you create a .Net .dll that has full access to the .Net framework, but can be loaded by any native language, just like you would with any .dll, and without the overhead of com interop.

Here is a simple example: http://cc.codegear.com/Item/22688

Bruce McGee
+5  A: 

In the Jedi Code Library (JCL) - free - there is a JclDotNet.pas, containing a class TJclClrHost, probably doing what you want:

  TJclClrHost = class(TJclClrBase, ICorRuntimeHost)
  private
 FDefaultInterface: ICorRuntimeHost;
 FAppDomains: TObjectList;
 procedure EnumAppDomains;
 function GetAppDomain(const Idx: Integer): TJclClrAppDomain;
 function GetAppDomainCount: Integer;
 function GetDefaultAppDomain: IJclClrAppDomain;
 function GetCurrentAppDomain: IJclClrAppDomain;
  protected
 function AddAppDomain(const AppDomain: TJclClrAppDomain): Integer;
 function RemoveAppDomain(const AppDomain: TJclClrAppDomain): Integer; 
  public
 constructor Create(const ClrVer: WideString = '';
   const Flavor: TJclClrHostFlavor = hfWorkStation;
   const ConcurrentGC: Boolean = True;
   const LoaderFlags: TJclClrHostLoaderFlags = [hlOptSingleDomain]);
 destructor Destroy; override;
 procedure Start;
 procedure Stop;
 procedure Refresh;
 function CreateDomainSetup: TJclClrAppDomainSetup;
 function CreateAppDomain(const Name: WideString;
   const Setup: TJclClrAppDomainSetup = nil;
   const Evidence: IJclClrEvidence = nil): TJclClrAppDomain;
 function FindAppDomain(const Intf: IJclClrAppDomain; var Ret: TJclClrAppDomain): Boolean; overload;
 function FindAppDomain(const Name: WideString; var Ret: TJclClrAppDomain): Boolean; overload;
 class function CorSystemDirectory: WideString;
 class function CorVersion: WideString;
 class function CorRequiredVersion: WideString;
 class procedure GetClrVersions(VersionNames: TWideStrings); overload;
 class procedure GetClrVersions(VersionNames: TStrings); overload;
 property DefaultInterface: ICorRuntimeHost read FDefaultInterface implements ICorRuntimeHost;
 property AppDomains[const Idx: Integer]: TJclClrAppDomain read GetAppDomain; default;
 property AppDomainCount: Integer read GetAppDomainCount;
 property DefaultAppDomain: IJclClrAppDomain read GetDefaultAppDomain;
 property CurrentAppDomain: IJclClrAppDomain read GetCurrentAppDomain;
  end;
Stefan Schultze
Am I blind or there is no example how to use it?
Lukas Cenovsky
+1  A: 

We hosted the CLR in the Delphi process, which is pretty easy.

This page was pretty helpful: http://interop.managed-vcl.com/netinterop_csharp.php

Cameron MacFarland
A: 

Found an answer at the free Delphi.NET sourceforge project.

Osama ALASSIRY
+2  A: 

See my question for end to end example of hosting CLR in Delphi with JCL.

Lukas Cenovsky