AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi Var Parameter in C++

Ein Thema von NickelM · begonnen am 8. Jul 2011 · letzter Beitrag vom 11. Jul 2011
Antwort Antwort
Seite 1 von 2  1 2      
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#1

Delphi Var Parameter in C++

  Alt 8. Jul 2011, 14:56
Hallo zusammen,

Ich habe eine DLL geschrieben und wollte testen, ob man sie auch in C++ verwenden kann.
Dafür hab ich mir eine C++ IDE (CodeBlocks) geholt und mal versucht das umzusetzten.
Ich muss dazusagen, dass ich mich mit C++ nicht wirklich auskenne und jetzt an ein Problem gekommen bin.
Ich lade meine DLL dynamisch in C++. Die ersten 2 Funktionen konnte ich umsetzten nach langem Probieren.
Nun hab ich nichts zu meinem Problem in google gefunden. (zumindest wusste ich nicht wie ich richtig danach googlen soll..meine versuche sind fehlgeschlagen)

Nun meine Funktion wird so in der DLL in Delphi deklariert
Delphi-Quellcode:
function ReadPackedFileData(PackFileHandle : Integer; DataPos,DataSize : Integer; var Bytes : TBytes): Integer; stdcall;
//Falls jemand fragt : TBytes = array of Byte;
So der Knackpunkt ist das var TBytes (nebenbei was macht var in einer Funktion bei delphi?, ich wies das die funktion dadurch nur variablen annimmt bei delphi, aber was bedeutet das var eigentlich? Also auf der "Speicherbereichsebene" )

Versucht habe ich es so in einer Konsolenanwendung

Code:
typedef int (*TReadPackedFileData) (int ,int ,int, byte* &bytes);

int main()
{
HMODULE hIns;
TReadPackedFileData ReadPackedFileData;
byte* bytes;

hIns=LoadLibrary("E://DLLTestC/pack.dll");
if(hIns > 0)

ReadPackedFileData=(TReadPackedFileData)GetProcAddress(hIns,"ReadPackedFileData");
ReadPackedFileData(Test1->FileHandle,Test2->FileDataPos,Test2->FileSizeCompressed, bytes);
//Test1 und Test2 sind struct Pointer, die auch funken, die Daten hol ich mir mit den 2 anderen Funktionen. Was auch funkt.
}
Danke im vorraus
Gruß NickelM
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#2

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 15:00
Durch das Var kennzeichnest Du einen Call by Reference, d.h. der Funktion wird keine Kopie der Daten übergeben, sondern das Original, womit aus der Funktion auch direkt in die Daten geschrieben werden kann.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#3

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 15:26
hmm okay...gut jetzt hab ich auch was gefunden was mir hilft...gut okay aber wie mach ich dynamischen array in c++?

wenn ich es so mache
Code:
typedef int (*TReadPackedFileData) (int ,int ,int, byte[]&);
bekomm ich den fehler : das der array keine größe hat...
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#4

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 15:31
Tut mir Leid, meine C++-Kenntnisse gehen nahe gegen 0, da kann ich Dir nicht weiterhelfen. Gibt es dort eigentlich dynamische Arrays?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Robotiker
(Gast)

n/a Beiträge
 
#5

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 15:42
Gibt es dort eigentlich dynamische Arrays?
Im C++ Builder wird auf Delphi Arrays über eine Templateklasse zugegriffen:
http://docwiki.embarcadero.com/VCL/e...m.DynamicArray

D.h. solche Array dürften mit normalem C++ nicht kompatibel sein.
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 15:57
Hmm okay ich hab mal was gemacht gehabt mit PByte und array of Byte..mal gugen ob das da auch so möglich ist.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

AW: Delphi Var Parameter in C++

  Alt 8. Jul 2011, 18:26
Dynamische Arrays (TBytes) sind Delphi-Typen. Man kann sich zwar sicher die Arbeit machen und irgendwie darauf aus anderen Programmiersprachen zugreifen aber wenn die interne Speicherstruktur von dynamischen Arrays geändert wird hast du ein Problem.
Ist "var Bytes : TBytes" wirklich das was du willst? Daten sollen in die Dll rein gegeben werden, dort änderbar sein und sollen dann zurück kommen? Oder willst du vielleicht nur Daten rein geben. Oder sollen die Daten innerhalb von TBytes nur modifizierbar sein aber die Größe des Arrays bleibt unverändert?

Am besten schaust du dir dazu einige Beispiel der Win-Api an. Dort ist es üblich das man der Funktionen einen Buffer übergibt und die Größe mitgibt (Anzahl der Elemente bzw. möglichen Elemente). Wenn die Funktion dann feststellt das die Anzahl der möglichen Elemente nicht ausreicht wird dieser Wert korrigiert.

Delphi-Quellcode:
function DoSomething(Buffer: PByte; var Count: Word): Boolean;
begin
  if Count < NeededSize then
    result := False
  else
  begin
    move(SomeStuff^, Buffer^, Count);
    result := True;
  end;
  Count:=NeededSize;
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#8

AW: Delphi Var Parameter in C++

  Alt 9. Jul 2011, 12:50
Hmm also die Funktion macht folgendes :

okay ich schreib mal den gesammten Code der Funktion rein. Es hängt nur an der einen. Die werte, wenn ich sie in C++ ausgeben stimmen auch.
Nur das mit PByte, wie ich es jetzt gemacht hab, geht nicht so...vermutlich immer Zugriefsverletzung unter C++. In Delphi funkt es.

Delphi-Quellcode:
//DLL Funktion
function ReadPackedFileData(PackFileHandle : Integer; DataPos : Integer; DataSize : Integer; var Bytes : PByte): Integer; stdcall;
var BytesStream : TBytesStream;
    ReadBytes,EndPackBytes : TBytes;
    RByte : Byte;
    ZLibStream : TZDecompressionStream;
begin
   FileSeek(PackFileHandle,DataPos,0);
   SetLength(ReadBytes,DataSize);
   If FileRead(PackFileHandle,ReadBytes[0],DataSize) = DataSize then
   begin
    BytesStream := TBytesStream.Create(ReadBytes);
    ZLibStream := TZDecompressionStream.Create(BytesStream);

    while ZLibStream.Read(RByte,1) = 1 do
    begin
    SetLength(EndPackBytes,High(EndPackBytes)+2);
    EndPackBytes[High(EndPackBytes)] := RByte;
    end;
    Result := High(EndPackBytes)+1;
    GetMem(Bytes,Result);
    Move(EndPackBytes[0],Bytes^,Result);
    ZLibStream.Free;
    BytesStream.Free;

   end
   else
   Result := -1;
end;
So funkt es in Delphi :

Delphi-Quellcode:
var I : Integer;
    Bytes : TBytes;
    BLength : Integer;
    PB : PByte;
begin
    If String(PackedFileInfo^.FileName) = FileName then
    begin
     BLength := ReadPackedFileData(FPackInfo.FileHandle,
     PackedFileInfo^.FileDataPos,
     PackedFileInfo^.FileSizeCompressed,
     PB);
     if BLength > -1 then
     begin
     SetLength(Bytes,BLength);
     System.Move(PB^,Bytes[0],BLength);
     Result := TMemoryStream.Create;
     Result.Write(Bytes[0],High(Bytes));
     Result.Position := 0;
     Bytes := nil;
     end;
    end;
end;

So und so versuch ich sie aufzurufen (die Integer werte stimmen...') :

Code:
typedef int (*TReadPackedFileData) (int ,int ,int, byte*&);

int main()
{
byte* bytes = NULL;
int Bcount;

//Dynamisch geladen
Bcount = ReadPackedFileData(Test1->FileHandle,Test2->FileDataPos,Test2->FileSizeCompressed, bytes);
}
Der Sinn davon ist das ich die entpackten Daten zurückgeben will.
Da es nicht wie in Delphi mit TBytes geht, wollte ich den Pointer auf den anfange (wie ich auch denke hinbekommen habe) zurückgeben.
Damit man dann mit C++ ähnlichen Funktionen wie Move von Delphi darauf zugreifen kann.
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.

Geändert von NickelM ( 9. Jul 2011 um 12:53 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#9

AW: Delphi Var Parameter in C++

  Alt 9. Jul 2011, 13:02
Delphi-Dynamische Arrays sind Compilermagic, die C so nicht kennt. Der übliche Weg in C ist entweder ein "byte[0]"-Array plus separater Längenangabe, oder ein Pointer auf den Array-Elementtyp, auch mit separater Längenangabe.
Beides ist dann zu Delphi kompatibel, wenn man in den Methoden einen Pointer auf das erste Element des Delphi-Arrays übergibt (@MyArray[0]), aber du musst in jedem Fall Länge separat mit übergeben lassen.

So ein Funktionskopf könnte in einer Delphi-DLL dann so aussehen:
Delphi-Quellcode:
procedure Foo(myArray: PByte; aLength: Integer);
var
  bytes: TByteArray;
begin
  SetLength(bytes, aLength);
  Move(bytes[0], myArray, aLength);
.
.
end;
Danach solltest du eine Kopie in "bytes" haben, die man mit den ganzen Komfort von Delphi ansprechen kann, obgleich nur ein Pointer plus Länge übergeben wurden. Falls das übergebene Array verändert werden soll, musst du es nachher natürlich zurück kopieren. Etwas "undelphiischer" wäre gleich die Verwendung von Pointerarithmetik wie in C, nicht ganz sooo schmuck, aber auch kein Beinbruch.

Ah, ich sehe grad, dass du das Array befüllen willst! Dann wirst du nicht umhin kommen eine Funktion anzubieten, die die erwartete Länge vorab liefert, weil das Array muss vom Host-Programm zuvor ja komplett reserviert werden. Üblich ist es dafür die selbe Funktion zu nehmen, welche die Länge als result hat, und wenn für den Container ein NULL (nil) übergeben wird, gibt's eben nur Länge ohne Daten. Der Host muss dann also 2x aufrufen, ein mal mit NULL, und danach mit korrekt dimensioniertem Array (=Pointer auf sein erstes Element).
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium ( 9. Jul 2011 um 13:05 Uhr)
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#10

AW: Delphi Var Parameter in C++

  Alt 11. Jul 2011, 01:50
Achso..du meinst ich muss im Hostprogramm erst den speicher reservieren und dan die Referenz zu dem PByte übergeben in C++?

Und in Delphi das mit GetMem kann mir dan sparen ober?
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:48 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