Hallo Leute,
ich habe ein Pluginbasierendes Programm geschrieben und hab nun jede Menge Probleme zu bewältigen, die ich nicht einmal verstehe.
Die Plugins sind einfache
Win32 DLL's.
Die
DLL's besitzen nur 2 Hauptfunktionen, die mit der Delphi Standardkonvetion "register" aufegrufen werden. Die Funktionen heissen "init" und "start" und sehen wie folgt aus.
Delphi-Quellcode:
{DLL Plugin}
type
TGet =
function(link,cookie:pchar;redirect,sendcookie:boolean;
var location,rawheaders:pchar):pchar ;
stdcall;
TPost =
function(link,params,cookie:pchar;redirect,sendcookie:boolean;
var location,rawheaders:pchar):pchar ;
stdcall;
var
CBGet : TGet ;
CBPost : TPost ;
function initcb(
const get,post:Pointer):pchar ;
begin
@CBGet := Get ;
@CBPost := Post ;
Result := '
Plugin_1' ;
end;
function start(link:pchar):pchar ;
var
Location, RawHeaders : pchar
begin
Result := CBPost('
http://www.google.de','
','
',false,false,Location,RawHeaders) ;
end;
Wie man sieht, übergebe ich Init 2 Zeiger auf Funktionen im Hauptprogramm.
Get dient dazu den
HTML Code einer beliebigen Seite abzurufen und Post steht eben für einen Post Request zur Verfügung. Diese beiden Fukntionen werden aber mit "stdcall" als Aufrufkonvention aufgerufen, da ich glaube gelesen zu haben, dass Callbackfunktionen sich nur mit "stdcall" vertragen.
Für die echten Funktionen im Hauptprogramm habe ich
Indy 9 verwendet und sie sehen folgerndermaßen aus.
Delphi-Quellcode:
{Hauptprogramm}
function PLGHTTPGet(link,cookie:pchar;redirect,sendcookie:boolean;var location,rawheaders:pchar):pchar ; stdcall ;
var
IDHTTP : TIdHTTP ;
begin
IDHTTP := TIdHTTP.Create(nil);
IDHTTP.HandleRedirects := redirect ;
if sendcookie then
begin
IDHTTP.AllowCookies := True ;
IDHTTP.Request.CustomHeaders.Text := cookie ;
end
else
IDHTTP.AllowCookies := False ;
try
Result := pchar(IDHTTP.Get(link)) ;
except
Result := 'failed' ;
end;
location := pchar(IDHTTP.Response.Location) ;
rawheaders := pchar(IDHTTP.Response.RawHeaders.text);
IDHTTP.Free ;
end;
function PLGHTTPPost(link,params,cookie:pchar;redirect,sendcookie:boolean;var location,rawheaders:pchar):pchar ; stdcall;
var
Parameters : TStringList ;
HTTP : TIdHTTP ;
begin
HTTP := TIdHTTP.Create(nil);
Parameters := TStringList.Create ;
Parameters.Add(params) ;
HTTP.HandleRedirects := redirect ;
if sendcookie then
begin
HTTP.AllowCookies := True ;
HTTP.Request.CustomHeaders.Text := cookie ;
end
else
HTTP.AllowCookies := False ;
try
Result := PChar(HTTP.Post(link,Parameters)) ;
except
Result := 'failed' ;
end;
location := PCHar(HTTP.Response.Location) ;
rawheaders := pChar(HTTP.Response.RawHeaders.text);
Parameters.Free ;
HTTP.Free ;
end;
Die
DLL Plugins fasse ich in einem array mit einem Record zusammen und rufe sie nacheinander auf.
Delphi-Quellcode:
{Hauptprogramm}
..
...
try
MemoOutput.text := PlgArray[i].start(PChar(Link)) ;
except
...
..
Soweit sogut.
Es klappt auch alles wunderbar und wird auch richtig ausgeführt, aber dann passieren unter bestimmten Umständen ganz komische Sachen.
Wenn ich die Post Funktion ca. 20 - 30 in einem Plugin aufrufe, dann bekommt das Hauptprogramm nichts mehr als Ergebnis von "start" zurück, obwohl in der
DLL alles richtig ablaüft und sie auch das richtige Result zurückgibt.
Dann wird es aber noch abgefahrener und das Hauptprogramm bleibt nach dem Aufruf der
DLL einfach sporadisch an irgendeiner Stelle hängen.
Jetzt kann ich es mir absolut nicht erklären.
Es kommt auch nie eine
AV, aber manchmal ein Runtime Error.
Könnt ihr einen Fehler entdecken.
Mache ich vielleicht grundsätzlich etwas falsch?
Danke im Voraus.
PS: Ich benutze Delphi 2006.