title: Calling a Delphi DLL from a C# .NET application
body: <p><strong>EDIT: I've posted a better implementation of this, below. I left this here so the responses would make sense.</strong></p>
  
  <p>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.</p>
  
  <p>This was compiled using Delphi 2007 and VS 2010. I suspect it will work fine in other versions as well.</p>
  
  <p>Here's the Delphi code. Remember to include version information in the project.</p>
  
  <pre><code>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.
  </code></pre>
  
  <p>Here's the C# code:</p>
  
  <pre><code>using System;
  using System.Runtime.InteropServices;
  
  namespace CsharpApp
  {
      class Program
      {
          // I added DelphiLibrary.dll to my project (NOT in References, but 
          // "Add existing file"). In Properties for the dll, I set "BuildAction" 
          // to None, and "Copy to Output Directory" to "Copy always".
          // Make sure your Delphi dll has version information included.
  
          [DllImport("DelphiLibrary.dll", 
                     CallingConvention = CallingConvention.StdCall, 
                     CharSet = CharSet.Ansi)]
          public static extern 
              string DelphiFunction(int inputInt, string inputString,
                                    out int outputInt, out string outputString);
  
          static void Main(string[] args)
          {
              int inputInt = 1;
              string inputString = "This is a test";
              int outputInt;
              string outputString;
  
  
  // NOTE: I've posted a better version of this below. You should use that instead.
  
  
              Console.WriteLine("inputInt = {0}, intputString = \"{1}\"",
                                inputInt, inputString);
              var errorString = DelphiFunction(inputInt, inputString,
                                               out outputInt, out outputString);
              if (errorString != null)
                  Console.WriteLine("Error = \"{0}\"", errorString);
              else
                  Console.WriteLine("outputInt = {0}, outputString = \"{1}\"",
                                    outputInt, outputString);
              Console.Write("Press Enter:");
              Console.ReadLine();
          }
      }
  }
  </code></pre>
  
  <p>I hope this information helps someone else to not have to pull their hair out as much as I did.</p>