title: Writing a .NET (C#) dll for a Delphi App
body: <p>A friend asked me about writing a dll in C# for a delphi app. He wants to communicate with it using this function decleration:</p>
  
  <pre><code>function OpenAddOnFile(const mafCode: PWideChar; const mafFilePath: PWideChar;
                     const mafVersion: PWideChar): Pointer; stdcall;
  </code></pre>
  
  <p>The problem I have is translating it to C#. PWideChar isnt available etc... I've tried it like that:</p>
  
  <pre><code>public Pointer OpenAddOnFile(
      [MarshalAs(UnmanagedType.LPWStr)]string mafcode,     
      [MarshalAs(UnmanagedType.LPWStr)]string maffilepath,  
      [MarshalAs(UnmanagedType.LPWStr)]string mafversion
  )
  </code></pre>
  
  <p>But its not working for now :)</p>
  
  <p>Further more how can I return a Pointer to my form in C#?</p>
  
  <p>Can someone help me please?
  Thanks in advance!</p>
  
  <p>Edit:\</p>
  
  <p>He gave me this additional code:
  I asked him for the function call, he gave me this info:</p>
  
  <pre><code>unit unAddOn;
  
  interface
  
  uses
     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
     System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
     Vcl.ComCtrls;
  
  function LoadAddOnFile(aPath: String; aVersion: String; var aFilePath: String;
                         var aCode: String): Boolean;
  
  const
      AddOnExt: String = '.maf';
  
  implementation
  
  function LoadAddOnFile(aPath: String; aVersion: String; var aFilePath: String;
                     var aCode: String): Boolean;
  type
     TOpenAddOnFile = function(const mafCode: PWideChar; const mafFilePath: PWideChar;
                          const mafVersion: PWideChar): Pointer; stdcall;
     TCloseAddOnFile = procedure(var mafCode: PWideChar; var mafFilePath: PWideChar;
                            var mafQuitPopUp: PWideChar); stdcall;
  var
     CloseAddOnFile: TCloseAddOnFile;
     OpenAddOnFile: TOpenAddOnFile;
     AddOnMainForm: TForm;
     AddOnHandle: THandle;
     mafQuitPopUp: PWideChar;
     mafFilePath: PWideChar;
     mafVersion: PWideChar;
     mafCode: PWideChar;
  begin
     Result := True;
     mafQuitPopUp := PWideChar(EmptyStr);
     mafFilePath  := PWideChar(aFilePath);
     mafCode      := PWideChar(aCode);
     mafVersion   := PWideChar(aVersion);
  
     try
     AddOnHandle := LoadLibrary(PWideChar(aPath));
  if (AddOnHandle &lt;&gt; 0) then
  begin
    @OpenAddOnFile  := GetProcAddress(AddOnHandle, 'OpenAddOnFile');
    @CloseAddOnFile := GetProcAddress(AddOnHandle, 'CloseAddOnFile');
  
    if (@OpenAddOnFile &lt;&gt; nil) then
    begin
      AddOnMainForm := OpenAddOnFile(mafCode, mafFilePath, mafVersion);
      AddOnMainForm.Position := poScreenCenter;
      AddOnMainForm.ShowModal;
      if (@CloseAddOnFile &lt;&gt; nil) then
      begin
        CloseAddOnFile(mafCode, mafFilePath, mafQuitPopUp);
      end;
      FreeAndNil(AddOnMainForm);
      Application.ProcessMessages;
    end;
  end;
  
  if not (mafQuitPopUp = PWideChar(EmptyStr)) then
  begin
    ShowMessage(mafQuitPopUp);
  end;
  aFilePath := String(mafFilePath);
  aCode := String(mafCode);
  except
  Result := False;
  end;
  end;
  
  end.
  </code></pre>