Alex Rivera | Logout

Calling a Delphi DLL from a C# .NET application

Asked 2010-11-12T09:49:20.180
34

EDIT: I've posted a better implementation of this, below. I left this here so the responses would make sense.

I've done numerous searches for the correct method for writing a DLL in Delphi, and being able to call it from C#, passing and returning strings. A lot of the information was incomplete or incorrect. After much trial and error, I found the solution.

This was compiled using Delphi 2007 and VS 2010. I suspect it will work fine in other versions as well.

Here's the Delphi code. Remember to include version information in the project.

library DelphiLibrary;

uses SysUtils;

// Compiled using Delphi 2007.

// NOTE: If your project doesn't have version information included, you may
// receive the error "The "ResolveManifestFiles" task failed unexpectedly"
// when compiling the C# application.

{$R *.res}

// Example function takes an input integer and input string, and returns
// inputInt + 1, and inputString + ' ' + IntToStr(outputInt) as output
// parameters. If successful, the return result is nil (null), otherwise it is
// the exception message string.


// NOTE: I've posted a better version of this below. You should use that instead.

function DelphiFunction(inputInt : integer; inputString : PAnsiChar;
                        out outputInt : integer; out outputString : PAnsiChar)
                        : PAnsiChar; stdcall; export;
var s : string;
begin
  outputInt := 0;
  outputString := nil;
  try
    outputInt := inputInt + 1;
    s := inputString + ' ' + IntToStr(outputInt);
    outputString := PAnsiChar(s);
    Result := nil;
  except
    on e : exception do Result := PAnsiChar(e.Message);
  end;
end;

// I would have thought having "export" at the end of the function declartion
// (above) would have been enough to export the function, but I couldn't get it
// to work without this line also.
exports DelphiFunction;

begin
end.

Here's the C# code:

using System;
u
Edit
Report

1 Answer

0

It is easier to retireve a string using PString:

function DelphiFunction(inputString : PAnsiChar;
                    var outputStringBuffer : PString;
                    var errorMsgBuffer : PString)
                    : WordBool; stdcall; export;
var 
  s : string;
begin
  try
    s := inputString;
    outputStringBuffer:=PString(AnsiString(s));
    Result := true;
  except
    on e : exception do
    begin
      s:= 'error';
      errorMsgBuffer:=PString(AnsiString(e.Message));
      Result := false;
    end;
  end;
end;

In c# then:

    const int stringBufferSize = 1024;

    var  str = new    IntPtr(stringBufferSize);

    string loginResult = Marshal.PtrToStringAnsi(str);
answered 2013-04-30T09:52:24.297

Your Answer