Einzelnen Beitrag anzeigen

barana

Registriert seit: 14. Apr 2007
5 Beiträge
 
#1

Callback Funktionen und DLL?

  Alt 15. Jun 2007, 16:10
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.
  Mit Zitat antworten Zitat