Hum, it seams that skalogryz-code is not a joke, so be careful, it could be a bomb...
Look at that :
The program =>
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes,
libunit; // the pseudo-library
begin
ProcExported('Proc1(1,2,3)');
end.
The pseudo-library =>
unit libunit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, internalprocess;
procedure Proc1(a,b,c: Integer);
procedure ProcExported(theproc: string); /// Exported in library
implementation
procedure Proc1(a,b,c: Integer); /// not exported in library
begin
writeln(a);
writeln(b);
writeln(c);
end;
procedure ProcExported(theproc: string); /// Exported in library
var
VProcess: TInternalProcess;
begin
VProcess:= TInternalProcess.Create;
try
VProcess.CommandLine := theproc;
VProcess.Execute;
finally
VProcess.Free;
end;
end;
procedure HiddenProc(Var Result : TFPExpressionResult; Const Args : TExprParameterArray);
begin
Proc1(args[0].ResInteger, args[1].ResInteger, args[2].ResInteger);
Result.ResInteger:=0;
end;
initialization
RegisterProc('proc1', 'III', @HiddenProc);
end.
And the bomb =>
unit internalprocess;
{$mode delphi}{$H+}
interface
uses
Classes, SysUtils, fpexprpars;
Type
TFPExpressionResult = fpexprpars.TFPExpressionResult;
TExprParameterArray = fpexprpars.TExprParameterArray;
TFPExprFunctionCallBack = fpexprpars.TFPExprFunctionCallBack;
{ TInternalProcess }
TInternalProcess = class(TObject)
private
fCommandLine : string;
public
LastError : string;
procedure Execute;
property CommandLine: string read fCommandLine write fCommandLine;
end;
procedure RegisterProc(const name, types: string; ptr: TFPExprFunctionCallBack);
implementation
var
IntProc : TStringList;
procedure RegisterProc(const name, types: string; ptr: TFPExprFunctionCallBack);
begin
IntProc.AddObject(name+'|'+types, TObject(@ptr));
end;
{ TInternalProcess }
procedure TInternalProcess.Execute;
var
exp : TFPExpressionParser;
i : Integer;
nm : string;
j : Integer;
ptr : TFPExprFunctionCallBack;
begin
try
exp:=TFPExpressionParser.Create(nil);
try
for i:=0 to IntProc.Count-1 do begin
ptr:=TFPExprFunctionCallBack(IntProc.Objects[i]);
nm:=IntProc[i];
j:=Pos('|',nm);
exp.Identifiers.AddFunction(Copy(nm, 1, j-1), 'I', Copy(nm, j+1, length(nm)), ptr);
end;
exp.Expression:=fCommandLine;
exp.Evaluate;
finally
exp.Free;
end;
except
on E: Exception do
LastError := E.Message;
end;
end;
initialization
IntProc := TStringList.Create;
finalization
IntProc.Free;
end.
With that code, i get exactly what i want ( but, yes, some "hidden" code to add to original code...).
=> @ Marcov and Skalogryz : ok, you win, where is the bug (if there is one) ?