View Single Post
 
Old 05-16-2018, 09:57 AM
kolbasz kolbasz is offline
Senior Member
 
Join Date: Nov 2013
Posts: 840
Default

Contrary to the popular belief, it's perfectly fine to pass strings over dll boundary, like this(see attachment, Delphi 2007):
Code:
library CallbackDll;

uses
  SysUtils,
  Classes;

{$R *.res}

type
  PCallback = ^TCallback;
  TCallback = record
    FResult: Integer;
    FInStr: String;
    FOutStr: String;
  end;
  TOnCallback = procedure(ACallback: PCallback);

var
  OnCallback: TOnCallback = nil;
  Callback: PCallback;

procedure Send_Value;
begin
  Callback.FResult := 1000 - StrToIntDef(CallBack.FInStr, 0);
  Callback.FOutStr := 'Test ' + Callback.FInStr;
  if Assigned(OnCallback) then
    OnCallback(Callback);
end;

procedure InitCallback(AOnCallback: TOnCallback; ACallback: PCallback); stdcall;
begin
  OnCallback := AOnCallback;
  Callback := ACallback;
  Send_Value;
end;  
                 
exports
  InitCallback;

begin
end.
Code:
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfMain = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  fMain: TfMain;

implementation

{$R *.dfm}

type
  PCallback = ^TCallback;
  TCallback = record
    FResult: Integer;
    FInStr: String;
    FOutStr: String;
  end;

var
  Callback: PCallback;
  LibHandle: THandle;

procedure DoOnCallback(ACallback: PCallback);
begin
  ShowMessage('Callback from dll:' + sLineBreak +
              'FResult: ' + IntToStr(ACallback.FResult) + sLineBreak +
              'FOutStr: ' + ACallback.FOutStr);
end;

procedure CallDll(const ALibName, AInStr: String);
type
  TOnCallback = procedure(ACallback: PCallback);
  TInitCallback = procedure(AOnCallback: TOnCallback; ACallback: PCallback); stdcall;
var
  InitCallBack: TInitCallback;
begin
  @InitCallBack := GetProcAddress(LibHandle, PChar('InitCallback'));
  if @InitCallBack <> nil then
  begin
    CallBack^.FInStr := AInStr;
    InitCallBack(@DoOnCallback, Callback);
  end;
end;

procedure TfMain.Button1Click(Sender: TObject);
begin
  Randomize;
  CallDll('CallbackDll.dll', IntToStr(Random(1000) + 1));
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
  LibHandle := LoadLibrary(PChar('CallbackDll.dll'));
  New(Callback);
end;

procedure TfMain.FormDestroy(Sender: TObject);
begin
  DisPose(Callback);
  if LibHandle > 0 then
    FreeLibrary(LibHandle)
end;

end.
Attached Files
File Type: zip CallBack.zip (54.6 KB, 1 views)

Last edited by kolbasz; 05-16-2018 at 10:01 AM.