Create dll in C# and use in Delphi 7

Asked

Viewed 3,931 times

4

I need to create a dll in C# so I can use it in Delphi.

I tried the following:

I created a basic dll with a sum method, but when calling it in Delphi does not return anything, it would be like the created method does not exist.

Below the code in C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ClasseCom
{
    [ClassInterface(ClassInterfaceType.None)]
    public class soma        
    {
        public soma() { }
        public double somar(int a, int b)
        {
            return a + b;
        }

    }
}

Here as I try to call it at Delphi 7:

procedure TForm1.Button1Click(Sender: TObject);
var
  Handle : THandle;
  somar : TSomaDll;
  total : Double;

begin

  Handle:=LoadLibrary ('ClasseCom.dll');
  if Handle <> 0 then begin

    @somar:=GetProcAddress(Handle, 'somar');

    if @somar <> nil then
      total := somar(1, 2);

    FreeLibrary (Handle);

  end;

  ShowMessage(FloatToStr(total));

end;

In Delphi the variable @soma is returning as nil.

I also used an application called DDL Export Viewer that shows the methods of dll, but for mine shows nothing, and trying to validate the State Registration provided by sintegra presents the method of the same.

  • A . Net DLL is not standard, so you won’t get it this way. There must be a way to do this, I have some ideas, but I’m not going to risk having no experience and solid knowledge with it.

  • Ariel, I have a question with basically the same title http://answall.com/q/8107/5846

  • The solution is to declare the classes in C# as Comvisible and consume in Delphi as Activex instead of DLL Windows. Delphi is very good at importing Activex objects, generating Wrappers for them and managing the life cycle, very cool. I worked on many projects like this. Unfortunately I don’t have access now to any code that can yield an answer, but go down this path that you won’t regret: Comvisible in C# and consumption as Activex in Delphi. There must be examples on the net. Good luck!

  • http://answall.com/questions/47254/com-interop-com-client-e-server/47328#47328

2 answers

2

As has been said before the way is for you to consume the Assembly as with:


using System;
using System.Runtime.InteropServices;

namespace ClasseCom
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(ISoma))]
    [Guid("E8D53EED-3B2F-45A8-BB29-CC111BB426D1")]
    public class Soma : ISoma
    {
        public double Somar(int a, int b)
        {
            return a + b;
        }
    }

    [ComVisible(true)]
    [Guid("97D1968E-DC7F-45BD-BD0E-1AC822D95264")]
    public interface ISoma
    {
        double Somar(int a, int b);
    }
}

With this you will have your class exposed via COM. From there you use the tlbexp utility to export your tlb Assembly:

tlbexp.exe Caminho\Do\Seu\Assembly\AssemblyDaClasseCOM.dll

The easiest way to access the utility (assuming you have Visual Studio installed) is through prompt Visual Studio (Developer Command Prompt) developer command that can be found inside the Visual Studio folder in the Start menu.

After generating tlb using tlbexp just import it in Delphi as you would with any Activex. As was said by @Caffé the importer of Delphi will generate Wrappers for those COM classes that will help you a lot.

An important point to be remembered at this moment is that to use you will have to have this Assembly . NET registered on your machine, using the utility Regasm

If you want to use without registration (which I strongly recommend to avoid the famous DLL Hell) you can take a look at this article: With Registration Free

That’s it, any doubt Just talk.

Edit

Example code in Delphi (Working):


uses
  MeuComponenteCom_TLB;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  LSoma: ISoma;
  LResultado: Double;
begin
    LSoma := CoSoma.Create;
    LResultado := LSoma.Somar(1, 2);

    ShowMessage(FloatToStr(LResultado));
end;

end.

Obs.: The example was made using Delphi XE7.

Edit2

If you have any questions about how to add a TLB follow some images that show where you can do this:

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

2

I’ve had to do this integration of C# and Delphi and hit my head a lot rsrs..

Good in your C#, you install via nuget o Unmanagedexports

And in your C# mark with the Dllexport attribute the method you want Delphi to "see".

Mark your class also with [ComVisible(true)] and defines a Guid

Your project must be configured to compile on the x86 platform.

For example:

[Guid("14fd1190-df04-488c-ab0f-b120ea3e3f3a")]
[ComVisible(true)]
public class Exported
{

    [DllExport]
    public static int func(int a, int b) 
    {
        Thread.CurrentThread.SetApartmentState(ApartmentState.STA); //é necessario se você quiser que o delphi abra um form do C#

        Form1 f = new Form1();
        f.ShowDialog();

        return a + b;
    }
}

And in your Delphi declares Function, referenced dll, remembering that dll must be in the same directory as your Delphi application (.exe)..

function func(var a: Integer, var b: Integer ): Integer; stdcall; external suaDllEmCSharp.dll;

and during your code just call

...
if func(1,2)=3 then
...

I remember what I tried to do to load the dll at runtime, as you did, but I did not succeed.

I had to make the static statement.

I hope I’ve helped...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.