Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Embeded Lisp in Delphi (https://www.delphipraxis.net/13553-embeded-lisp-delphi.html)

HPW 20. Dez 2003 22:27


Embeded Lisp in Delphi
 
Mit dem heute auf http://www.newlisp.org/ freigegebenen Release 7.400 von newLISP (Open Source) ist es einfach möglich eine Lisp-DLL in Delphi einzubetten und das GUI von Delphi zu nutzen.

Hier ein paar Zeilen Code zur Einbindung:

Code:
type
  TNewLispCall = function(string1: PChar): PChar; stdcall;
Code:
VAR     DllCall     : TNewLispCall;
...
...
           Handle := 0;
           Handle := LoadLibrary( Pchar( 'newlisp.dll' ));
           if Handle <> 0 then
              Begin
              @DllCall := GetProcAddress( Handle, PChar( 'dllEvalStr' ) );
              if Assigned( DllCall ) then
                begin
                  RetStr := NIL;
                  RetStr := DllCall( PChar( DllParam1 ) );
                end;
              end;

HPW 25. Jul 2008 07:16

Re: Embeded Lisp in Delphi
 
Als Nachtrag hier noch ein Beispiel wie man callbacks aus Lisp realisieren kann:

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1  : TEdit;
    Button3: TButton;
    Edit2: TEdit;
    Button4: TButton;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen } 
  public
    { Public-Deklarationen } 
    // This is the procedure that I call from newLisp.
    procedure xRefresh1(param1 : PChar); stdcall;
    procedure xRefresh2(param1,param2 : PChar); stdcall;
    procedure xRefresh3(param1,param2,param3 : PChar); stdcall;
  end;

var
  Form1: TForm1;
  DllNewLisp     : THandle;
  newLispEvalStr : function(argExpression: pchar): pchar; stdcall;

implementation

{$R *.DFM} 

procedure openNewLispLibrary;
begin
  DllNewLisp := LoadLibrary('newlisp.dll');
  if (DllNewLisp < HINSTANCE_ERROR) then
    raise Exception.Create('newlisp.dll' + ' library can not be loaded or not found. ' + SysErrorMessage(GetLastError));
  try
    { load an address of required procedure} 
    @newLispEvalStr := GetProcAddress(DllNewLisp, 'newlispEvalStr');
  finally
    {unload a library} 
  end;
end;

procedure TForm1.xRefresh1(param1 : PChar); stdcall;
begin
  showmessage(param1);
  showmessage(IntToStr(Strlen(param1)));
end;

procedure TForm1.xRefresh2(param1, param2 : PChar); stdcall;
begin
  showmessage(param1+' / '+param2);
  showmessage(IntToStr(Strlen(param1))+' / '+IntToStr(Strlen(param2)));
end;

procedure TForm1.xRefresh3(param1, param2, param3 : PChar); stdcall;
begin
  showmessage(param1+' / '+param2+' / '+param3);
  showmessage(IntToStr(Strlen(param1))+' / '+IntToStr(Strlen(param2))+' / '+IntToStr(Strlen(param3)));
end;

procedure registerAndCall1(txtparam : String);
var
  newlispstr: string;
begin
  // I'm using Lutz code to link Pascal function to be used in newLisp.
  newlispstr := '(set ''foo print)' + 
                '(cpymem (pack "ld" 265) (first (dump foo)) 4)' + 
                '(cpymem (pack "ld" ' + 
                IntToStr(integer(@TForm1.xRefresh1)) + ') (+ (first (dump foo)) 12) 4)' + 
                '(cpymem (pack "ld" "foo") (+ (first (dump foo)) 8) 4)';
  newLispEvalStr(pchar(newlispstr));

  newlispstr := '(foo nil "'+ txtparam + ' is the String from the edit-field")';
  newLispEvalStr(pchar(newlispstr));
end;

procedure registerAndCall2(txtparam1, txtparam2 : String);
var
  newlispstr: string;
begin
  // I'm using Lutz code to link Pascal function to be used in newLisp.
  newlispstr := '(set ''foo1 print)' + 
                '(cpymem (pack "ld" 265) (first (dump foo1)) 4)' + 
                '(cpymem (pack "ld" ' + 
                IntToStr(integer(@TForm1.xRefresh2)) + ') (+ (first (dump foo1)) 12) 4)' + 
                '(cpymem (pack "ld" "foo1") (+ (first (dump foo1)) 8) 4)';
  newLispEvalStr(pchar(newlispstr));

  newlispstr := '(foo1 nil "'+ txtparam1 + ' is the String from the edit-field" "Test2:'+ txtparam2 + '")';
  newLispEvalStr(pchar(newlispstr));
end;

procedure registerAndCall3(txtparam1, txtparam2, txtparam3 : String);
var
  newlispstr: string;
begin
  // I'm using Lutz code to link Pascal function to be used in newLisp.
  newlispstr := '(set ''foo2 print)' + 
                '(cpymem (pack "ld" 265) (first (dump foo2)) 4)' + 
                '(cpymem (pack "ld" ' + 
                IntToStr(integer(@TForm1.xRefresh3)) + ') (+ (first (dump foo2)) 12) 4)' + 
                '(cpymem (pack "ld" "foo2") (+ (first (dump foo2)) 8) 4)';
  newLispEvalStr(pchar(newlispstr));

  newlispstr := '(foo2 nil "'+ txtparam1 + ' is the String from the edit-field" "Param2:'+ txtparam2 + '" "Param3:'+ txtparam3 + '")';
  newLispEvalStr(pchar(newlispstr));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   openNewLispLibrary;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  registerAndCall1(Edit1.Text);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  registerAndCall2(Edit1.Text, Edit2.Text);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  registerAndCall3(Edit1.Text, Edit2.Text, Edit3.Text);
end;

end.

alzaimar 25. Jul 2008 07:26

Re: Embeded Lisp in Delphi
 
Interessant!

Ich weiss zwar theoretisch, das Lisp cool ist, aber praktisch kam ich mit Pascal/C-Script bisher wunderbar aus.

Welche Vorteile im praktischen Einsatz bietet die Verwendung einer LISP-Engine, ggü. einer Pascal-Script Engine? Hast Du es im Einsatz?

mkinzler 25. Jul 2008 07:48

Re: Embeded Lisp in Delphi
 
Sicherlich gut für String/Listenbearbeitung. Mochte aber Lisp nie besonderst

HPW 25. Jul 2008 11:26

Re: Embeded Lisp in Delphi
 
Zitat:

Ich weiss zwar theoretisch, das Lisp cool ist, aber praktisch kam ich mit Pascal/C-Script bisher wunderbar aus.

Welche Vorteile im praktischen Einsatz bietet die Verwendung einer LISP-Engine, ggü. einer Pascal-Script Engine? Hast Du es im Einsatz?
Wenn man von Lisp spricht muss man natürlich die verschiedenen Varianten erst mal unterscheiden.
Hier sind nicht die grossen Ansi-Common-Lisp Implementationen wie Lispworks/Allegro/Clisp/CormanLisp/... gemeint.

newLISP ist eine sehr kleine aber mächtige Version von Lisp in der Tradition der frühen Lisp-Implementationen wie XLisp etc..
(Info auf www.newlisp.org)

Nun zu praktischen Vorteilen:
newLISP ist extrem klein (DLL < 200KB, gepackt < 100 KB).
newLISP ist für einen Interpreter sehr schnell und mächtig.
Lisp unterscheidet nicht Code und Daten. (z.B.Code-Morphing)

Ich bin zu newLISP gekommen, weil ich als Autocad/Autolisp-Programmierer nach einer kompatiblen Lösung zur Programmierung ausserhalb von Autocad gesucht habe.
Wenn man nun Daten zwischen externen Programmen und Autocad austauschen will, ist es sehr hilfreich wenn das externe Programm nativ Lisp versteht.
Dazu ist es hilfreich wenn man als Programmierer die Hauptlogik innerhalb der gleichen Programmier-Sprache schreiben/warten kann.
Nur für das GUI und rechenintensive Aufgaben nutzt man dann Delphi.

Zu guter Letzt bin ich der Author des newLISP-Plugins für das Authorensystem neobook ( www.neosoftware.com )(in delphi geschrieben!):

http://www.hpwsoft.de/anmeldung/html...neobook14.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz