Autor Beitrag
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1667
Erhaltene Danke: 305

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Di 22.08.17 22:48 
Hallo Forum

Problemstellung:
In einem vorherigen Topic hier galt es Funktionen aus einer (nativen) DLL in Delphi aufzunehmen.
Eine Headerdatei (aus einem C-Projekt) ist mit dabei, die folgende Datentypen entsprechend definiert:

ausblenden LibFT260.h
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
typedef unsigned long   u32;
typedef unsigned long long u64;

#ifdef __x86_64__
typedef unsigned int uint32;
typedef signed int   int32;
#else
typedef unsigned long uint32;
typedef signed long   int32;
#endif

Ich habe an dieser Stelle stur den Typ DWord (Pascal) für uint32, sowie Integer (Pascal) für int32 benutzt.
Dennoch bin ich ein wenig verunsichert, was diese (Compiler-) Fallunterscheidung angeht, denn sie wird einen Grund haben, den ich im Moment nicht nachvollziehen kann.

Wie ist long in dem Zusammenhang zu verstehen?

Ich habe nach Antworten gesucht und bin dabei auf diese Tabelle gestoßen:

ausblenden C++-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
     Specifier     |      Type
unsigned           |  unsigned int  // 32bit Integer ohne Vorzeichen ?
unsigned int       |  unsigned int
signed             |  int // 32bit Integer mit Vorzeichen ?
signed int         |  int 
int                |  int
unsigned long int  |  unsigned long int // Keine Ahnung ?!
unsigned long      |  unsigned long int
signed long int    |  long int
signed long        |  long int  
long int           |  long int
long               |  long int

Setze ich die Suche fort, ist die Rede davon, dass long / long int ein 64bit Integer in C/C++ ist.
In C# ist long ebenso also 64bit Integer bekannt, schaut man sich die Vordefinierten Typen an.
Soviel ich weiss ist mit long long in C/C++ ein 64bit Integer gemeint, und genau das verwirrt mich etwas.
Im Artikel Data Type Ranges ist ein long eindeutig ein 32bit Integer.

Was stimmt nun?

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)


Zuletzt bearbeitet von Frühlingsrolle am Fr 25.08.17 18:21, insgesamt 3-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4153
Erhaltene Danke: 822


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 22.08.17 23:15 
Unter 32 bit ist long = int. Bei 64bit Systemen kommt es auf OS/Compiler/Compilereinstellungen an.
Unter Windows und einem Microsoft Compiler ist auch bei 64bit OS long = int = 32bit. Unter *nix OS'en ist long eher gleich long long also 64bit.

Zitat:
Was stimmt nun?


Alles was du gefunden hast ist im richtigen Kontext vermutlich richtig.

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1667
Erhaltene Danke: 305

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Di 22.08.17 23:34 
Besten Dank Ralf Jansen!Wie würdest du die Fallunterscheidung im Codefragment aus der Sicht von Windows (32/64 bit) deuten?

Die Tabelle muss ich nacheditieren. Da ist mir beim Abschreiben ein Fehler unterlaufen.

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 3531
Erhaltene Danke: 689

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Mi 23.08.17 09:08 
Die Tabelle listet nur auf, was man in C oder C++ angeben kann, um einen bestimmten Datentyp zu definieren, d.h.
ausblenden C
1:
2:
3:
4:
signed long int a;
signed long     b;
long int        c;
long            d;

definieren alle einen "long int" (es gibt auch noch den Datentyp "long double", d.h. "long" ist sprachtechnisch gesehen nur ein "qualifier" (zusätzliches Kennzeichen)).

Hinzu kommt, daß der C und C++ Sprachstandard jeweils nur Mindestgrößen für die Datentypen vorgibt:
ausblenden Quelltext
1:
2:
3:
4:
short     >= 16 bit (2 Byte)
int       >= 16 bit (2 Byte)
long      >= 32 bit (4 Byte)
long long >= 64 bit (8 Byte)

Jeder Compilerhersteller definiert dann für sich die entsprechenden Datengrößen (welche möglichst passend zum Prozessor sind, um möglichst effizienten Code zu erzeugen).

Und bei dem Code der Library wird eben anhand des Makros __x86_64__ festgelegt, wie die beiden Aliasnamen uint32 und int32 definiert sind (d.h. auf welchen konkreten Datentypen diese beruhen).
Wenn du also eine DLL in Delphi ansprechen willst, dann mußt du genau wissen, mit welchem Compiler (und dessen Einstellung x86 oder x64) diese kompiliert wurde.

Bei deiner Library kannst du also wegen der Namen davon ausgehen, daß die beiden Datentypen einen 32-Bit Integer verwenden (egal ob für x86 oder x64 kompiliert).

PS: "C/C++" gibt es nicht ;-)

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1667
Erhaltene Danke: 305

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 23.08.17 10:02 
Sehr gut erklärt, danke Th69!
Gut, ich werde es in Zukunft vermeiden, C/C++ zu schreiben. Ist eine Unsitte aus dem Internet, die ich mir angeignet habe. :D
Zitat:
Bei deiner Library kannst du also wegen der Namen davon ausgehen, daß die beiden Datentypen einen 32-Bit Integer verwenden (egal ob für x86 oder x64 kompiliert).

Genau darin sehe ich ein Problem. Meine Pascal Übersetzung geht an dieser Stelle immer von einem 32-Bit Integer aus. Wenn aber die importierten DLL Funktionen an jenen Stellen einen 64-Bit Integer brauchen, sprich, der Wert geht über den Wertebereich eines 32-Bit Integers (mit/ohne Vorzeichen) hinaus, dann gibt's ein Problem.

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
Tastaro
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 391
Erhaltene Danke: 22



BeitragVerfasst: Mi 23.08.17 11:04 
Da fällt mir immer diese uralte Frage ein:

Was ist der Unterschied zwischen einem Pascal- und einem C-Programmierer?

Der Pascal-Programmierer weiß wie lang seine Datentypen sind. :)

Für diesen Beitrag haben gedankt: hydemarie
Symbroson
ontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 31
Erhaltene Danke: 2

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: So 08.10.17 21:29 
user profile iconTastaro hat folgendes geschrieben Zum zitierten Posting springen:
Da fällt mir immer diese uralte Frage ein:

Was ist der Unterschied zwischen einem Pascal- und einem C-Programmierer?

Der Pascal-Programmierer weiß wie lang seine Datentypen sind. :)


Dem muss ich wiedersprechen.
speziell für integer kannst du stdint.h importieren - da weiß man nachher immer wie groß die sind - egal auf welcher Plattform. Im zweifelsfall sizeof(type) ausgeben.

Und ich bezweifle sehr stark dass pascal Programmiere im Schnitt die Datentypengröße besser kennen als c bzw. c++ programmierer.

bei Java kann ich mir das vorstellen, aber das kann und will ich vorerst nicht verstehen, geschweigedenn lernen.
Bin halt ein typischer Linux-Fan :p

LG

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 431
Erhaltene Danke: 77

Win7, Win81
XE4, VS2012
BeitragVerfasst: Mo 09.10.17 00:05 
Och, in Pascal ist das ziemlich streng formuliert.

ShortInt = 8 Bit Signed, int8 als Alias
Byte = 8 Bit unsigned, UInt8 als Alias
SmallInt = 16 Bit signed, Int16 als Alias
Word = 16 Bit Unsigned, UInt16 als Alias
Integer = 32 Bit signed, Int32 oder auch LongInt als Alias
Cardinal = 32 Bit unsigned, UInt32 oder auch LongWord als Alias
int64 = 64 Bit signed
UInt64 = 64Bit unsigned

Es gibt aber einen Typen, bei dem es vom System abhängt: NativeInt bzw. NativeUInt. Der ist 32bittig unter 32bit-Systemen und 64bittig unter 64-Bit-Systemen.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: Frühlingsrolle
Symbroson
ontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 31
Erhaltene Danke: 2

Linux Raspbian, Win10
C, C++, Python, JavaScript, Delphi, Casio Basic, Basic Stamp
BeitragVerfasst: Mo 09.10.17 03:43 
in c ist es ähnlich:
char: 1B
short: 2B
int: 4B | (16bit)2B
long: 4B
long long: 8B

float: 4B
double: 8B
long double: 10B

pointer: 4B

mit stdint.h tragen die Typen ihre Größe im Namen und sind Plattformunabhängig
intx_t / uintx_t wobei x=8,16,32,64

[Edit] also ich hab jetzt doch nochmal nachgeschaut und folgenden Thread gefunden, der deine Aussage leider bestätigt :roll: : stackoverflow.com/qu...int-in-c-programming

Absr wie gesagt - zur Not sizeof(type) - dann kann einen nichts überraschen oder fleich stdint.h

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1667
Erhaltene Danke: 305

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Di 10.10.17 08:17 
user profile iconTh69 hat's eh schon erklärt, worauf es ankommt. Müsste man NativeInt und NativeUInt in Pascal selber definieren, wie würde das vom Code her aussehen?

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 431
Erhaltene Danke: 77

Win7, Win81
XE4, VS2012
BeitragVerfasst: Di 10.10.17 09:12 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
  {$IFDEF WIN32}
  NativeInt = integer;
  NativeUInt = Cardinal;
  {$ELSE}
  NativeInt = int64;
  NativeUInt = UInt64;
  {$ENDIF}


So ungefähr.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: Frühlingsrolle
hydemarie
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 375
Erhaltene Danke: 48



BeitragVerfasst: Di 10.10.17 10:55 
user profile iconSymbroson hat folgendes geschrieben Zum zitierten Posting springen:
in c ist es ähnlich:
char: 1B


Wobei du natürlich, wenn du schon Plattformunabhängigkeit als Vorteil von irgendwas nennst, daran denken solltest, dass du außer stdint.h auch limits.h einbindest und mit CHAR_BIT statt mit "Byte" (denn das ist keine Konstante) rechnest... ;)
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1667
Erhaltene Danke: 305

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 11.10.17 15:46 
Danke OlafSt für deine Hilfestellung bezüglich Pascal.

Bezogen auf meinen 1.Beitrag:

ausblenden LibFT260.h
1:
2:
3:
4:
5:
6:
7:
#ifdef __x86_64__
typedef unsigned int uint32;
typedef signed int   int32;
#else
typedef unsigned long uint32;
typedef signed long   int32;
#endif

Hier wird z.B. auf Win7 64-Bit der else-Zweig ausgeführt. Soll auch so sein. Wird nun eine Win32 oder eine Win64 Anwendung darauf erstellt/ausgeführt, so entspricht die Größe der Aliasse uint32 und int32 - 4 Byte (kompiliert mit VS 2012).
So oder so läuft es auf einen 32-Bit Integer hinaus, zumindest auf Windows. Andere OS sind für mich nicht relevant.


Das Thema hat sich erledigt !!!

_________________
„Wo andere blind der Wahrheit folgen, denk daran ... Nichts ist wahr!" (Assassin's Creed I-II)