views:

395

answers:

4

Hi,

Could you please tell me if .NET component can be used with Delphi 2009 and, if so, could you please send me some example code.

Thanks in advance.

+4  A: 

Not in delphi for Win32.

You can use Delphi PRISM for this.

You can also check CrossTalk or Hydra

Hugues Van Landeghem
+3  A: 

Yes it is possible to use a .net component in a win32 program. The unfortunate news is that it is not very simple to do yourself, and I would strongly recommend Hydra.

skamradt
+ 1 for RemObjects Hydra.
RRUZ
A: 

You can use .NET components with Delphi for .NET which is part of the RAD studio

Adam Craig Johnston
Not anymore, Delphi.NET has been replaced with Delphi Prism since Delphi 2009.
Alan Clark
Delphi for .NET is part of Rad Studio 2009
Adam Craig Johnston
+2  A: 

There are several ways of doing it and traditional COM/Interop is just one way to do it.

Another way is to use the already existing infrastructure that is built into the CLR to support COM/Interop and mixed-mode C++/CLI.

  • The CLR has excellent support for marshaling interface references to and from IUnknown (And every Delphi interface fulfills that requirement)
  • You can turn .Net assemblies into real DLLs and export functions with any language
  • I've written an MSBuild task that does this completely transparent: http://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
  • Combine those 2 things and you can get your .Net component as interface reference w/o the need to fight with COM and clsids/progids

Lucky for you, I've answered a very similar question in another forum already. So I already had some sample code to start with. ;-)

What I show here might not be your cup of tea.

  • It requires at least some knowledge of .Net that you maybe do not want to get involved with too much.
  • There are manual steps on both sides required and even though the flexibility you gain can easily make it more than worth it, flexibility might simply not be a requirement. Thus classic COM could be an option.

At the end of the day, I wouldn't use classic COM myself. Unless it really makes sense. (Like writing COM-Addins for Office)

In VisualStudio, you can use the refactor/extract interface wizard to get an interface from your component that has the methods that you require.

You need to provide these 3 Attributes

[ComVisible(true)] 
[Guid("Create a GUID yourself"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IYourInterface
  • "ComVisible" is required or the CLR will not create the required runtime-callable wrapper (RCW) (the thing that will be seen from Delphi)
  • The GUID is required to identify interfaces, the GUID has to be the same in the Delphi and .Net version of your interface
  • "ComInterfaceType.InterfaceIsIUnknown" tells the CLR that the RCW should implement IUnknown. Without it, you won't be able to use it in Delphi. Because in Delphi, every interface is IUnknown.

For the sake of keeping it simple, I assume your component has jut one simple method. Create a classlibrary in VisualStudio and follow the steps from the other page. (To be able to export functions)

[ComVisible(true)] 
[Guid("Create a GUID yourself"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IYourInterface
{
   void DoSomething(int value);
}

public class YourComponent : IYourInterface
{
   public void DoSomething(int value)
   {
     return value + 1;
   }
}

static class Exports
{
   [DllExport("createyourcomponent")]
   public static void CreateInstance([MarshalAs(UnmanagedType.Interface)]out IYourInterface instance)
   {
     instance = new YourComponent();
   }
}

In Delphi, you can wrap this interface in a component if you wish. Which would hide the fact that .Net is involved:

type
  IYourInterface = interface
  ['{Create a GUID yourself}']//Control+Shift+G in Delphi
    // important, safecall is used by COM/Interop
    procedure DoSomething(aValue : Integer); safecall; 
  end;  

  TYourComponent = class(TComponent)
  private
    fInnerInstance : IYourInterface;
  public
    procedure DoSomething(aValue : Integer);
    constructor Create(aOwner : TComponent);
  end;

implementation

procedure CreateManagedInstance(out aInstance : IYourInterface); 
  stdcall; external 'YourDotNetLibraryName' 
               name 'createyourcomponent';

constructor TYourComponent.Create(aOwner : TComponent);
begin
  inherited Create(aOwner);
  CreateManagedInstance(fInnerInstance);
end;

procedure TYourComponent.DoSomething(aValue : Integer);
begin
  fInnerInstance.DoSomething(aValue);
end;

Disclaimer: I didn't have an IDE handy, so there could be typos or other mistakes in the sample code...

Robert Giesecke