AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Bitweise Parameter füllen in Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

Bitweise Parameter füllen in Delphi

Ein Thema von ognif · begonnen am 28. Jun 2019 · letzter Beitrag vom 29. Jun 2019
Antwort Antwort
ognif

Registriert seit: 28. Jun 2019
3 Beiträge
 
#1

Bitweise Parameter füllen in Delphi

  Alt 28. Jun 2019, 21:44
Hallo zusammen,

eigentlich bin ich C++ Entwickler, wurde jetzt aber in ein Delphi Projekt "verliehen" und soll dort aushelfen.
Ansich klappt das ganz gut, aber ich komme langsam an die Verständnisprobleme zwischen C++ und Delphi.

Es geht hier primär um den C++ Operator |= in Delphi. Ich habe zu dem Thema schon einiges gefunden aber irgendwie klappt nichts was es eigentlich soll, sofern ich es richtig verstehe.

Also als Einleitung:
Ich hbae in Delphi zwei Enumerations:
Code:
TCreateImageTask = (
  citCreate = 1,
  citVerify
);
und
Code:
TImageType = (
  itISO = 1,
  itBin
);
Sehen ja beide ersteinmal gleich aus.
Ich versuche die ganze Zeit, TCreateImageTask in einen Paramater zu bekommen.

Hierzu habe ich als Vorlage genommen:
Code:
function TSampleVCL.GetPossibleImageTypes: TImageTypes;
var W:word;
begin
    CheckActive;
    DLL.GetPossibleImageFormats(@W);
    Result:=[];
    if (W and BS_IMG_ISO)<>0 then Result:=Result+[itISO];
    if (W and BS_IMG_BIN)<>0 then Result:=Result+[itBin];
end;
Dieser Code ist aus einer VCL Komponente. Funktioniert einwandfrei.

Das ganze habe ich jetzt versucht in eine andere Funktion zu bringen:
Code:
function TfrmMain.GetImageTask: TCreateImageTask;
begin
    Result:=[];
    if chkCreate.checked then Result:=Result+[citCreate];
    if chkVerify.checked then Result:=Result+[citVerify];
end;
Hier gibt mir Delphi beim compilieren aus:
[dcc32 Fehler] Main.pas(619): E2010 Inkompatible Typen: 'TCreateImageTask' und 'Set'
[dcc32 Fehler] Main.pas(620): E2008 Inkompatible Typen
[dcc32 Fehler] Main.pas(621): E2008 Inkompatible Typen
[dcc32 Fehler] Main.pas(239): E2065 Ungenügende Forward- oder External-Deklaration: 'TfrmMain.GetCreateTypes'

Wieso meckert Delphi hier, wenn Delphi mit einer fast identischen Funktion in einer VCL damit super klarkommt?

Das Problem ist, dass ich in Delphi eine Funktion füttern muss, welche die Deklaration hat:
Code:
function CreateImage(ImagePath, BadSectorsPath: string; ImageType: TImageType; Task: TCreateImageTask; VerifySectorBuffer: integer; FullCapacity: boolean):boolean;
Task: TCreateImageTask muss dabei bitweise gefüllt sein. Also citCreate oder citVerify alleine oder zusammen.
Hinweis: Übergeb ich nur citCreate oder citVerify wird die Funktion einwandfrei ausgeführt.

Es wird am Ende eine Funktion in einer C++ DL Laufgerufen mittels:

Code:
function TFoxBurnerSDK.CreateImage(ImagePath, BadSectorsPath: string; ImageType: TImageType; Task: TCreateImageTask; VerifySectorBuffer: integer; FullCapacity: boolean):boolean;
var CIP:TCreateImageParams;
begin
    CheckActive;
    StrPLCopy(CIP.ImagePath,ImagePath,MAX_PATH-1);
    StrPLCopy(CIP.BadSectorsFilePath,BadSectorsPath,MAX_PATH-1);
    CIP.ImageType:=integer(ImageType);
     CIP.VerifySectorBuffer:=integer(VerifySectorBuffer);
     CIP.FullCapacity:=BoolToByte(FullCapacity);
    FillReadErrorCorrectionParams(CIP.ErrorParams);
    Result:=DLLResult(FoxBurnerSDKCore.CreateImage(CIP,integer(Task)));
end;
In C++ mache ich einfach

Code:
__int8 dwOperation = 0;

   if (this->IsDlgButtonChecked(IDC_CHECK_CREATE))
   {
      dwOperation = BS_IMGTASK_CREATE;
   }

   if (this->IsDlgButtonChecked(IDC_CHECK_VERIFY))
   {
      dwOperation |= BS_IMGTASK_VERIFY;
   }

int32 res = ::CreateImage(cCreateImageParams, dwOperation);
Was verstehe ich da an der Funktionsweise nicht um das ganze bitweise zu befüllen? Besonders da es ja anscheinend in GetPossibleImageTypes funktioniert.

Geändert von ognif (28. Jun 2019 um 21:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#2

AW: Bitweise Parameter füllen in Delphi

  Alt 28. Jun 2019, 22:16
Wir sehen hier zwar die Deklaration von TImageType (singular), in dem Code gibt die Funktion aber TImageTypes (plural) zurück. Ich vermute, es gibt noch eine Deklaration in der Art TImageTypes = set of TImageType; Wenn es auch ein TCreateImageTasks = set of TCreateImageTask; gibt, dann kannst du den als Rückgabewert verwenden und der Code sollte funktionieren.

Es gibt halt einen Unterschied zwischen einem Aufzählungstypen und einem Set.

Außerdem kannst du auch einfach die Prozedur Include verwenden:

Delphi-Quellcode:
    Result:=[];
    if (W and BS_IMG_ISO)<>0 then Include(Result, itISO);
    if (W and BS_IMG_BIN)<>0 then Include(Result, itBin);
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
ognif

Registriert seit: 28. Jun 2019
3 Beiträge
 
#3

AW: Bitweise Parameter füllen in Delphi

  Alt 28. Jun 2019, 23:52
Vielen dank. In der Tat war kein Set vorhanden. Ich habe das jetzt erstmal in die VCL eingebaut.
Aber jetzt stimmt natürlich die Funktion

Code:
function TFoxBurnerSDK.CreateImage(ImagePath, BadSectorsPath: string; ImageType: TImageType; Task: TCreateImageTask; VerifySectorBuffer: integer; FullCapacity: boolean):boolean;
var CIP:TCreateImageParams;
begin
    CheckActive;
    StrPLCopy(CIP.ImagePath,ImagePath,MAX_PATH-1);
    StrPLCopy(CIP.BadSectorsFilePath,BadSectorsPath,MAX_PATH-1);
    CIP.ImageType:=integer(ImageType);
     CIP.VerifySectorBuffer:=integer(VerifySectorBuffer);
     CIP.FullCapacity:=BoolToByte(FullCapacity);
    FillReadErrorCorrectionParams(CIP.ErrorParams);
    Result:=DLLResult(FoxBurnerSDKCore.CreateImage(CIP,integer(Task)));
end;
Nicht mehr, da ja hier ein TCreateImageTask und nicht ein TCreateImageTasks erwartet wird.
Wenn ich jetzt die Funktion abändere, auf TCreateImageTasks wird das ganze dann wirklich noch am Ende
richtig an die DLL übergeben?
Code:
integer(Task)
  Mit Zitat antworten Zitat
ognif

Registriert seit: 28. Jun 2019
3 Beiträge
 
#4

AW: Bitweise Parameter füllen in Delphi

  Alt 29. Jun 2019, 09:36
Also ich habe jetzt noch eine Funktion hinzugefügt, um von dem "Set of" zu einem Integer zu gelangen.

Code:
function TfrmMain.SetToInt(const aSet;const Size:integer):integer;
begin
  Result := 0;
  Move(aSet, Result, Size);
end;
Aber irgendwie verstehe ich die Rückgaben nicht.

Wenn ich nur citCreate übergebe, bekomme ich 2 zurück.
Wenn ich nur citVerify übergebe, bekomme ich 4 zurück.
Bei beiden Werten bekomme ich 6 zurück.
Die Werte stimmen aber nicht mit der Enmueration überein.

Habe ich hier einen Denkfehler?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#5

AW: Bitweise Parameter füllen in Delphi

  Alt 29. Jun 2019, 10:41
Wenn ich nur citCreate übergebe, bekomme ich 2 zurück.
Wenn ich nur citVerify übergebe, bekomme ich 4 zurück.
Bei beiden Werten bekomme ich 6 zurück.
Die Werte stimmen aber nicht mit der Enmueration überein.
Tun sie doch!

Delphi-Quellcode:
TCreateImageTask = (
  citCreate = 1,
  citVerify
);
In Delphi hat das erste Element einer Enumeration den Ordinalwert 0 - außer man überschreibt das explizit, wie du das mit citCreate = 1 machst. Damit bekommt citCreate den Ordinalwert 1 und citVerify den Ordinalwert 2.

Baust du aus nun aus diesen Werten ein Set, daß du dann als Integer auswertest, dann entspricht ein citCreate einem Wert von 2^1 = 2 und citVerify von 2^2 = 4. Sind beide gesetzt, kommt logischerweise eine 6 heraus. Das passt zu deinen Beobachtungen.

Ich konnte jetzt aber noch keine Beschreibung entdecken, wie der Gegenpart (die DLL) die Daten erwartet. Deswegen kann ich auch nicht sagen, wie es richtig heißen muss.

Außerdem wäre die Angabe deiner Delphi-Version hilfreich. Nur so können wir hier qualifizierte Antworten zu geben, die auch von deiner Version unterstützt werden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort


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 03:38 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