Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi dynamisches Array an C++Dll übergeben (https://www.delphipraxis.net/114055-delphi-dynamisches-array-c-dll-uebergeben.html)

hubestef 19. Mai 2008 08:40


Delphi dynamisches Array an C++Dll übergeben
 
Hallo zusammen,

ich hab ein Problem mit Delphi und c++ und habe keine Ahnung mehr wie ich weitermachen sollte :cry: . Habe schon sehr sehr viel versucht aber noch nie di richtige Lösung gefunden.
Mein Problem ist folgendes.
Ich sollte ein dynamisches Array einer c++ dll übergeben. Diese sollte im Array Änderungen vornehmen. Nach der Ausführung der Dll muss ich aber das Array wieder im Delphi bearbeiten.
Die Übergabe an die Dll funktioniert super. Das Array wird auch von der Dll bearbeitet. Nur wenn ich in Delphi wieder darauf zugreifen möchte, dann bekomm ich nur ein leeres Array (lauter 0).
Kann mir bitte jemand sagen was da falsch sein könnte?

Die Deklaration in C++ sieht so aus:
extern "C" _declspec(dllexport) bool forwardFFTbool(double *out, double *dat, int x, int y, int z);

Das Einbinden der DLL in Delphi:
Delphi-Quellcode:
 forwardFFTbool:function(var outdat:PDouble;dat: TDim; x:Integer; y:Integer; z:Integer): boolean stdcall {$IFDEF WIN32} cdecl {$ENDIF};
  reverseFFTbool:function(var outdat:PDouble;dat: TDim; x:Integer; y:Integer; z:Integer): boolean stdcall {$IFDEF WIN32} cdecl {$ENDIF};
Die Methode in der alles berechnet wird lautet folgendermaßen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
   var g,gg,b:PDouble;//TDim;//PDouble; //PDinArray;
   res:Boolean;
   width, height, length,i,j,l,val,arlength,id:Integer;
   y:TDim;
   h1,h2:THandle;
   f:String;
begin
        width:= arrY;
        height:=arrX;
        length:=arrZ;
        arlength := height*length*width*SizeOf(Double)*2;
         h1:=GlobalAlloc(GHND,arlength);
         h2:=GlobalAlloc(GHND,arlength);
        g := GlobalLock(h1);
        b := GlobalLock(h2);

        res:= forwardFFTbool(g,arra,height,width,length);

       gg := @g;
       if res= true then begin
        SetLength(y,height*length*width*SizeOf(Double)*2);
        id := 0;
        for l:= 0 to length-1 do begin
           for i:=0 to Height-1 do begin
                for j:= 0 to Width -1 do begin
                     y[(height*width*l)+(i*Width +j)] := gg^;//g[(height*width*l)+(i*Width +j)];//g^;
                     Inc(gg);
                end;
           end;
        end;
     
        res := reverseFFTbool(b,y,height,width,length);

        if res= true then begin
        txtStatus.Text := 'RFFT Com ok!';
        txtStatus.Font.Color := clGreen;
        end else begin
          txtStatus.Text := 'RFFT Com not ok!';
          txtStatus.Font.Color := clRed;
        end;
        end else begin
          txtStatus.Text := 'RFFT Com not ok!';
          txtStatus.Font.Color := clRed;
        end;

        GlobalUnlock(h1);
        Globalfree(h1);
        GlobalUnlock(h2);
        Globalfree(h2);
end;
irgendwer eine Idee?
Danke im voraus
mfg
Stefan

SirThornberry 19. Mai 2008 08:46

Re: Delphi dynamisches Array an C++Dll übergeben
 
ehrlich gesagt seh ich in deinem Quelltext mit deiner Variablenbennennung etc. nicht durch.
Ich finde das du das ganze unnötig kompiliziert machst mit deinem GlobalAlloc etc. Du könntest doch auch ein normales Array nehmen und dann einen pointer auf das erste Element übergeben.
Und bist du dir sicher das es stdcall ist und nicht cdecl? Mit _declspec gibst du schließlich an das die Callingconvention cdecl ist.

sirius 19. Mai 2008 09:03

Re: Delphi dynamisches Array an C++Dll übergeben
 
Was auch immer genau du machen willst, aber schau dir mal VarArrayCreate an! Das ist eine Kapselung des Windows SafeArrays.
(Edit: Geht natürlich nur, wenn du auch auf die C++ Funktion Einfluss hast)

hubestef 19. Mai 2008 09:07

Re: Delphi dynamisches Array an C++Dll übergeben
 
Danke für die rasche Antwort. Brauch ich das GlobalAlloc und so zeugs nicht? ich war der Meinung, dass ich das brauche für die DLL.
Hab jetzt ein "normales" dynamisches Array mit SetLength erzeugt und einen Pointer darauf wie du gemeint hast. Funktioniert leider immer noch nicht.

mfg
Stefan

SirThornberry 19. Mai 2008 09:09

Re: Delphi dynamisches Array an C++Dll übergeben
 
nein, übergib nicht ein poiner auf das dynamische Array sondern einen Pointer auf das erste Element des Dynamischen Arrays.
Und bist du dir sicher das deine Funktion mit cdecl arbeitet und nicht mit stdcall?

OregonGhost 19. Mai 2008 10:48

Re: Delphi dynamisches Array an C++Dll übergeben
 
Zitat:

Zitat von SirThornberry
Und bist du dir sicher das deine Funktion mit cdecl arbeitet und nicht mit stdcall?

Um das mal klarzustellen: Die C-Deklaration enthält keinerlei Aufrufkonvention und dürfte somit cdecl sein. Mich irritiert aber bei der Delphi-Übersetzung, dass dort stdcall + cdecl drin vorkommen - macht der Compiler dann nicht stdcall draus oder gilt immer das letzte?

hubestef 19. Mai 2008 10:55

Re: Delphi dynamisches Array an C++Dll übergeben
 
Hallo SirThornberry

Ich hab jetzt mal eine kleine DLL geschrieben die im Grunde den gleichen Aufruf hat. Es funktioniert leider noch immer nicht, auch wenn ich einen Pointer auf das erste Element mache. cdecl oder stdcall machen auch keinen Unterschied. Kannst du dir bitte den Code noch einmal anschaun, ich glaub ich steh jetzt voll auf der Leitung. Danke

C++ Dll
Code:
 extern "C" _declspec(dllexport) bool add(double *res, double * dat, int size);


bool add(double * res, double *dat, int size){
   double * help;
   int i;
   int count =0;
   for (i = 0; i < size; i++){
      res[i] = dat[i] * 2;
      if (res[i] == 0)
         count ++;
   }
   if (count == 0)
      return true;
   else {
      return false;
   }
}
delphi Implementierung:
Delphi-Quellcode:
 type
 TDim = Array of Double;
  add:function(var outdat:PDouble;dat: TDim; size:Integer): boolean stdcall {$IFDEF WIN32} cdecl {$ENDIF};

procedure TForm1.Button2Click(Sender: TObject);
  var dat, res : TDim;
      size,i : Integer;
      result : Boolean;
      pres : PDouble;
begin
  size := 9;
  SetLength(dat,size);
  SetLength(res,size);

  pres:=@res[0];
  for i := 0 to size-1 do begin
    dat[i] := 2;
  end;

  result := add(pres,dat,size);
  if result = true then begin
        txtStatus.Text := 'add ok!';
        t1.text := FloatToStr(res[0]);
  end else begin
          txtStatus.Text := 'add failed!';
  end;

end;

jbg 19. Mai 2008 11:42

Re: Delphi dynamisches Array an C++Dll übergeben
 
Zitat:

Zitat von hubestef
var outdat:PDouble;

Doppelt gemoppelt funktioniert leider in der Programmierung nicht. Dadurch hättest du ein "double**" und nicht ein "double*". Mach das "var" weg.

Zitat:

stdcall {$IFDEF WIN32} cdecl {$ENDIF};
Das IFDEF kannst du dir sparen, denn WIN32 ist nicht definiert, wenn du es nicht von Hand definierst und dann würde ein Kompilierfehler auftreten da das syntaktisch nicht gültig ist.

hubestef 19. Mai 2008 12:24

Re: Delphi dynamisches Array an C++Dll übergeben
 
Danke für eure antworten.
Hab das Problem schon lösen können.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:57 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