title: Passing PChar's between a Delphi 2007 DLL and an XE6 EXE
body: <p>I have a DLL written in Delphi 2007 that I can't, for various reason, convert to being compiled in XE6.</p>
  
  <p>I have written a wee test app in XE6 that calls the DLL, and that's all fine, but I need to pass string data from the DLL to the exe, and I am using a PCHAR to do this.
  However, consuming the PCHAR in the XE6 exe is proving to be a bit of a pain.</p>
  
  <p>I read somewhere that in D2007 a PCHAR is actually a PANSICHAR, so I tried using a PANSICHAR and I make a call to the DLL but it just returns an empty string!</p>
  
  <p>I have tried various other types like PWIDECHAR, String, WideString, ShortString and PCHAR.
  PCHAR does return something that looks like a Wide String, but I am not sure if it actually is because it didn't cast when I tried it :-)</p>
  
  <p>So I am wondering what I am doing wrong? Am I passing the wrong type from the D2007 DLL? Should I be doing the consumption of the data differently in XE6?</p>
  
  <p><strong>-- EDIT --</strong>
  Ok, I didnt get any results based on Remy's idea, so I have included my code this time and I am sure the solution will be obvious to someone. I appreciate the help :-)</p>
  
  <p>This is the code for the DLL which is written in D2007:</p>
  
  <pre><code>library mydll;
  
    uses
      SysUtils
  
  type
    TOnCommandProc = procedure(sMessage:PAnsiChar);
  stdcall;
  
  var
    FOnCommandProc: TOnCommandProc = nil;
  
  procedure SetOnCommandProc(CallbackProc: TOnCommandProc);
  stdcall;
  begin
    FOnCommandProc := CallbackProc;
  end;
  
  procedure OnEventMessage(Data: String);
  var
   BuffSize: Integer;
   sOut: string;
   oData : PAnsiChar;
  begin
  
    sOut:=Data;
    BuffSize:=SizeOf(Char)*(Length(sOut)+1);
    getmem(oData, BuffSize);
    FillChar(oData^,BuffSize,0);
  
    if (Length(sOut)&gt;0) then
    begin
      Move(sOut[1], PAnsiChar(oData)^, BuffSize);
      FOnCommandProc(oData);
    end;
  end;
  
  procedure TryTheEvent;
  begin
    OnEventMessage('Hello');
  end;
  
  exports
    SetOnCommandProc name 'SetOnCommandProc',
    TryTheEvent name 'TryTheEvent';
  end.
  </code></pre>
  
  <p>This is the calling EXE code written in Delphi XE6:</p>
  
  <pre><code>unit Unit1;
  
  interface
  
  uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
  
  type
    TOnCommandProc = procedure(sMessage:PAnsiChar); stdcall;
  
    procedure SetOnCommandProc(CallbackProc: TOnCommandProc; sMessage:PAnsiChar); stdcall; external 'mydll.dll';
    procedure TryTheEvent; stdcall; external 'mydll.dll';
  
  type
    TForm1 = class(TForm)
      Button1: TButton;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure Button1Click(Sender: TObject);
    private
      { Private declarations }
      class procedure MyOnCommandProc(sMessage:PAnsiChar); stdcall; static;
      procedure OnCommand(sMessage : PAnsiChar);
  
    public
      { Public declarations }
    end;
  
  var
    Form1: TForm1;
  
  implementation
  
  {$R *.dfm}
  
  procedure TForm1.Button1Click(Sender: TObject);
  begin
    TryTheEvent;
  end;
  
  procedure TForm1.FormCreate(Sender: TObject);
  begin
    SetOnCommandProc(@MyOnCommandProc,0);
  end;
  
  procedure TForm1.FormDestroy(Sender: TObject);
  begin
    SetOnCommandProc(nil,0);
  end;
  
  class procedure TForm1.MyOnCommandProc(sMessage:PAnsiChar); stdcall;
  begin
    TForm1(sMessage).OnCommand(sMessage);
  end;
  
  procedure TForm1.OnCommand(sMessage :PAnsiChar);
  begin
    showmessage(sMessage);
  end;
  
  end.
  </code></pre>