Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Problem beim Übersetzen von C++ nach Delphi
Edmund Jenner-Braunschmie - Mi 27.12.06 18:09
Titel: Problem beim Übersetzen von C++ nach Delphi
Hallo,
ich bin gerade dabei, einen C++ Code ins Delphi zu übersetzen. Es werden Funktionen
einer DLL-Datei implementiert (Ansteuerung einer USB-Kamera).
Nun mein Problem: Wie übersetze ich die Variablen-Deklaration
Quelltext
1:
| typedef void* VRmUsbCamDevice; |
nach Delphi?
Vielen Dank vorab und wenn ich was genauer beschreiben soll - bitte posten.
lg edi
Hier ein kurzer Ausschnitt aus der C++ Datei:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| // ------------------------------------------------------------------------ // Device Management // ------------------------------------------------------------------------
typedef void* VRmUsbCamDevice;
typedef struct _VRmDeviceKey { VRmDWORD m_serial; const char* mp_manufacturer_str; const char* mp_product_str; VRmBOOL m_busy; void* mp_private; }VRmDeviceKey;
VRM_API VRmRetVal VRmUsbCamUpdateDeviceKeyList(); VRM_API VRmRetVal VRmUsbCamGetDeviceKeyListSize(VRmDWORD* fp_size); VRM_API VRmRetVal VRmUsbCamGetDeviceKeyListEntry(VRmDWORD f_index,VRmDeviceKey** fpp_device_key); VRM_API VRmRetVal VRmUsbCamGetVendorId(const VRmDeviceKey* fp_device_key,VRmWORD* fp_vendor_id); VRM_API VRmRetVal VRmUsbCamGetProductId(const VRmDeviceKey* fp_device_key,VRmWORD* fp_product_id); VRM_API VRmRetVal VRmUsbCamFreeDeviceKey(VRmDeviceKey** fpp_device_key); VRM_API VRmRetVal VRmUsbCamOpenDevice(const VRmDeviceKey* fp_device_key,VRmUsbCamDevice* fp_device); VRM_API VRmRetVal VRmUsbCamGetDeviceKey(VRmUsbCamDevice f_device,VRmDeviceKey** fpp_device_key); VRM_API VRmRetVal VRmUsbCamCloseDevice(VRmUsbCamDevice f_device); |
Moderiert von
Tino: Code-Tags hinzugefügt.
tommie-lie - Mi 27.12.06 18:39
Titel: Re: Problem beim Übersetzen von C++ nach Delphi
Leute, die Edmund heißen, sind mir zwar normalerweise sehr suspekt, aber ich will mal eine Ausnahme machen, weil's offensichtlich nicht der Stoiber-Edmund ist :mrgreen:
Edmund Jenner-Braunschmie hat folgendes geschrieben: |
Wie übersetze ich die Variablen-Deklaration Quelltext 1:
| typedef void* VRmUsbCamDevice; | nach Delphi? |
Das ist keine Variablendeklaration, das ist eine Typendefinition, wie man am typedef erkennen kann. Das Delphi-Äquivalent wäre
Delphi-Quelltext
1: 2:
| type VRmUsbCamDevice = Pointer; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type VRmUsbCamDevice = Pointer;
type VRmDeviceKey = _VRmDeviceKey; _VRmDeviceKey = packed record m_serial: VRmDword; mp_manufacturer_str: PChar; mp_product_str: PChar; mp_private: Pointer; end;
function VRmUsbCamUpdateDeviceKeyList(): VRmRetVal; function VRmUsbCamGetDeviceKeyListSize(fp_size: PVRmDWORD): VRmRetVal; |
Allerdings fehlen womöglich Aufrufkonventionen. Die stehen wahrscheinlich im Makro VRM_API, dessen Definition du nicht gepostet hast. Unter Umständen muss bei den Funktionsdeklarationen also noch mit stdcall oder cdecl hantiert werden.
Edmund Jenner-Braunschmie - Do 28.12.06 11:00
@ Thomas:
vorerst Danke, dass Du meinen offensichtlich vorbelasteten Vornamen akzeptierst :D.
Jedenfalls hast Du mir sehr geholfen. Mein Fehler war, dass ich stdcall statt
cdecl verwendet habe. Jetzt funktioniert's soweit - auskennen, was stdcall oder cdecl für'n
Unterschied macht, tu ich mich jedoch nicht - ist aber jetzt nicht so wichtig. Höchstens es
freut jemanden dies zu erklären - interessant wär's schon ;). - sonst kann ich mich
diesbezüglich irgendwann mal im Forum umsehen.
Wichtiger für mich ist nun eine Lösung für das nächste Problem bei der Übersetzung von
C++ nach Delphi!
nochwas: den Unterschied zwischen Typdefinition und Variablendeklaration kenne ich schon -
das war vorhin ein Versprecher - peinlich, peinlich :oops: !!
lg edi
Hier der C++ Code (was bedeutet das =1<<0 usw.?):
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| typedef enum _VRmImageModifier { VRM_STANDARD=0, VRM_VERTICAL_MIRRORED=1<<0, VRM_HORIZONTAL_MIRRORED=1<<1, VRM_INTERLACED_FIELD0=1<<2, VRM_INTERLACED_FIELD1=1<<3, VRM_INTERLACED_FIELD01=1<<4, VRM_INTERLACED_FRAME=1<<5, VRM_CORRECTION_LUT_1CHANNEL_8=1<<6, VRM_CORRECTION_LUT_1CHANNEL_10=1<<7, VRM_CORRECTION_LUT_4CHANNEL_8=1<<8, VRM_CORRECTION_LUT_4CHANNEL_10=1<<9, VRM_USER_ROI=1<<10, VRM_SUBSAMPLED=1<<11 }VRmImageModifier; |
Moderiert von
raziel: C#-Tags hinzugefügt
tommie-lie - Do 28.12.06 11:56
Edmund Jenner-Braunschmie hat folgendes geschrieben: |
Mein Fehler war, dass ich stdcall statt cdecl verwendet habe. Jetzt funktioniert's soweit - auskennen, was stdcall oder cdecl für'n Unterschied macht, tu ich mich jedoch nicht |
Die IA32 (x86-Prozessoren und kompatible) bietet natürlich von sich aus keine Methode, an Funktionsaufrufe mit Parametern zu versehen. Das nötige Mnemonic in Assembler ist CALL und nimmt als Parameter lediglich die Zieladresse der aufzurufenden Funktion an, keine zusätzlichen Funktionsparameter. Also muss man sich irgendwie darauf einigen, wie Parameter übergeben werden sollen, denn da gibt es diverse Möglichkeiten. Man könnte sie zum einen von rechts nach links auf den Stack schieben und es der aufgerufenen Funktion überlassen, sie wieder von dort runtezuholen (stdcall). Oder man könnte es genauso machen, aber derjenige, der die Funktion aufruft, muss den Stack wieder aufräumen (cdecl). Oder man könnte vereinbaren, daß einige Register des Prozessors die Parameter enthalten sollen und erst, wenn mehr Parameter benötigt werden, als Register vorhanden sind, wird der Stack verwendet (FastCall). Das alles nennt man Aufrufkonventionen, und wenn ein Compiler mehrere Aufrufkonventionen verwendet, muss man ihm mitteilen, welche er verwenden soll. In der Win32-API ist es üblich, stdcall zu verwenden, also ausschließlich den Stack für Parameterübergaben zu benutzen. Ein C-Compiler ohne Optimierung verwendet normalerweise cdecl als Aufrufkonvention.
Den Shift-Left-Operator hat Hape ja schon erklärt, eine andere gute C(++)-Referenz ist
http://cppreference.com/. Dort kannst du neben den Operatoren auch die unterschiedlichen Schlüsselwörter, Wertebereiche von Datentypen oder Standardfunktionen der Standard C Library oder der STL nachschlagen.
Edmund Jenner-Braunschmie - Do 28.12.06 16:00
Hi,
wiedermal Danke für alle Antworten.
Das mit SHL habe ich verstanden, das mit den Aurfufkonventionen glaube ich auch verstanden zu haben.
Quelltext
1: 2: 3:
| 1<<0 = 1; 1<<1 = 2; 1<<2 = 4; |
... ist also nur eine andere Schreibweise?! Soweit hab ich's dann verstanden - hoffe es passt.
Jetzt aber noch was Grundlegendes:
Diese Typdefinition
Quelltext
1:
| typedef enum _VRmImageModifier { VRM_STANDARD=0,VRM_VERTICAL_MIRRORED=1<<0, ..... } |
entspricht ja in Delphi etwa:
Delphi-Quelltext
1: 2:
| type _VRmImageModifier = (VRM_STANDARD, VRM_VERTICAL_MIRRORED, .... ) |
?? oder liege ich falsch?? Aber was mache ich in delphi dann mit =0, =1,... ??
Also irgendwas habe ich da noch nicht richtig "drauf"!!
Bitte um Hilfe
Moderiert von
raziel: Delphi-Tags hinzugefügt
wulfskin - Do 28.12.06 16:18
Hallo,
ich weiss leider nicht wie Delphi intern die Menge
Set of bearbeitet, aber vielleicht wäre das genau das passende.
Auf jeden Fall geht das aber ohne Menge und zwar so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
|
type VRM_STANDARD = 0; VRM_VERTICAL_MIRRORED = 1;
Func(VRM_STANDARD or VRM_VERTICAL_MIRRORED);
if (Var and VRM_STANDARD) > 0 then ; |
Das ist übrigens auch typisch für API-Befehl, die werden auch so übersetzt.
Viele Grüße,
Hape
wulfskin - Do 28.12.06 16:24
Nachtrag:
Hab gerade auch noch mal ganz kurz im Internet geforscht, weil es mich jetzt auch interessiert.
in
diesem Delphikurs [
http://www.epinasoft.com/delphikurs/dkk_sets.html] hab ich folgendes gefunden:
Zitat: |
[...] Sets können in Pascal maximal 256 Elemente umfassen und sind sehr effizient implementiert. Umfasst ein Set weniger als 32 Basiselemente, so versucht der Compiler das Set in einem Register der CPU zu halten, wodurch der Zugriff auf Sets und deren Bearbeitung extrem schnell wird. |
Das spricht doch stark dafür, dass Menge intern auch als 2er-Potenzen abgespeichert werden, würde ja auch Sinn.
Kurzum, folgendes sollte dann also auch funktionieren:
Delphi-Quelltext
1: 2: 3:
| type TVRmImageModifier = (VRM_STANDARD, VRM_VERTICAL_MIRRORED ); TVRmImageModifiers = set of TVRmImageModifier; |
Gruß Hape!
tommie-lie - Do 28.12.06 18:13
Damit verlässt man sich aber auf eine bestimmte Implementierung des Compilers. Solange das im Sprachstandard nicht definiert ist, würde ich nicht davon ausgehen, daß sich in Zukunft das Verhalten des DCC nicht ändern wird oder daß ein anderer Compiler (FreePascal, GNU Pascal) das genauso machen.
Damit kannst du bei einem selbstdefinierten Enumerationstyp (das, was du mit
type blubb = (EINS, ZWEI, DREI); machst) genau festlegen, welche Werte die einzelnen Elemente haben sollen. In Pascal sind ja die Enumerationselemente alle wie globale Konstanten benutzbar, und so kannst du ihnen bestimmte Werte zuweisen. Tust du das nicht, vergibt der Compiler Standardwerte.
BenBE - Mo 08.01.07 22:56
Edmund Jenner-Braunschmie hat folgendes geschrieben: |
Diese Typdefinition
typedef enum _VRmImageModifier { VRM_STANDARD=0,VRM_VERTICAL_MIRRORED=1<<0, ..... }
entspricht ja in Delphi etwa:
Delphi-Quelltext 1: 2:
| type _VRmImageModifier = (VRM_STANDARD, VRM_VERTICAL_MIRRORED, .... ); |
?? oder liege ich falsch?? Aber was mache ich in delphi dann mit =0, =1,... ?? |
In Delphi kannst Du dieser Werte problemlos übernehmen ;-) Das machen Enums mit ...
Normalerweise übersetzt man solche vorinitialisierten Enums aus C++ in Delphi jedoch einfach als Konstanten-Listen, da sie in C++ nix anderes sind.
Delphi-Quelltext
1: 2: 3: 4: 5:
| type _VRmImageModifier = ( VRM_STANDARD = 1 shl 0, VRM_VERTICAL_MIRRORED = 1 shl 1, ); |
Aber wie gesagt: Häufiger findet man in Delphi folgende Übersetzung:
Delphi-Quelltext
1: 2: 3: 4:
| const VRM_STANDARD = 1 shl 0; VRM_VERTICAL_MIRRORED = 1 shl 1; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!