![]() |
Bitweise Parameter füllen in Delphi
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:
und
TCreateImageTask = (
citCreate = 1, citVerify );
Code:
Sehen ja beide ersteinmal gleich aus.
TImageType = (
itISO = 1, itBin ); Ich versuche die ganze Zeit, TCreateImageTask in einen Paramater zu bekommen. Hierzu habe ich als Vorlage genommen:
Code:
Dieser Code ist aus einer VCL Komponente. Funktioniert einwandfrei.
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; Das ganze habe ich jetzt versucht in eine andere Funktion zu bringen:
Code:
Hier gibt mir Delphi beim compilieren aus:
function TfrmMain.GetImageTask: TCreateImageTask;
begin Result:=[]; if chkCreate.checked then Result:=Result+[citCreate]; if chkVerify.checked then Result:=Result+[citVerify]; end; [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:
Task: TCreateImageTask muss dabei bitweise gefüllt sein. Also citCreate oder citVerify alleine oder zusammen.
function CreateImage(ImagePath, BadSectorsPath: string; ImageType: TImageType; Task: TCreateImageTask; VerifySectorBuffer: integer; FullCapacity: boolean):boolean;
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:
In C++ mache ich einfach
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;
Code:
Was verstehe ich da an der Funktionsweise nicht um das ganze bitweise zu befüllen? Besonders da es ja anscheinend in GetPossibleImageTypes funktioniert.
__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); |
AW: Bitweise Parameter füllen in Delphi
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
Delphi-Quellcode:
Wenn es auch ein
TImageTypes = set of TImageType;
Delphi-Quellcode:
gibt, dann kannst du den als Rückgabewert verwenden und der Code sollte funktionieren.
TCreateImageTasks = set of TCreateImageTask;
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); |
AW: Bitweise Parameter füllen in Delphi
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:
Nicht mehr, da ja hier ein TCreateImageTask und nicht ein TCreateImageTasks erwartet wird.
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; 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)
|
AW: Bitweise Parameter füllen in Delphi
Also ich habe jetzt noch eine Funktion hinzugefügt, um von dem "Set of" zu einem Integer zu gelangen.
Code:
Aber irgendwie verstehe ich die Rückgaben nicht.
function TfrmMain.SetToInt(const aSet;const Size:integer):integer;
begin Result := 0; Move(aSet, Result, Size); end; 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? |
AW: Bitweise Parameter füllen in Delphi
Zitat:
Delphi-Quellcode:
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.
TCreateImageTask = (
citCreate = 1, citVerify ); 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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz