API string und zeiger

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

API string und zeiger

Beitrag von _JON_ »

Hallo Leute,

ich wundere mich gerade wie ich eine API deklarieren kann die sowohl Strings als auch Zeiger zu Strings akzeptiert.
Beispiel hier geht beides:

Code: Alles auswählen

ShellExecute_(0, 0, "notepad.exe", 0, 0, #SW_SHOWDEFAULT)
ShellExecute_(0, 0, @"notepad.exe", 0, 0, #SW_SHOWDEFAULT)
hier sind aber nur Strings erlaubt :?

Code: Alles auswählen

Prototype.i ProtoMessageBoxW(Window.i, Body.p-unicode, Title.p-unicode, Flags.i = 0)
If OpenLibrary(0, "User32.dll")
  MsgBox.ProtoMessageBoxW = GetFunction(0, "MessageBoxW")
  MsgBox(0, @"Hello", "World") ; hmm
EndIf
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: API string und zeiger

Beitrag von NicTheQuick »

Darf man fragen wieso du das machen willst? Reicht es nicht aus nur das eine oder nur das andere zu übergeben?
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Re: API string und zeiger

Beitrag von _JON_ »

Eine Möglichkeit reicht natürlich, mich wunder nur das die vordeklarierten beides akzeptieren.
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: API string und zeiger

Beitrag von NicTheQuick »

Naja, in Wirklichkeit wird bei beiden Aufrufen nur der Pointer übergeben. Purebasic hat das früher immer so gemacht und deswegen geht das wohl heute auch noch in bestimmten Ausnahmefällen.

Vielleicht macht das Beispiel hier es etwas klarer. Unicode darf nicht aktiviert sein.

Code: Alles auswählen

;Eigentliche API-Funktion
Procedure a(*pointer)
	Debug *pointer
	Debug PeekS(*pointer, -1, #PB_Ascii)
EndProcedure

;Version, bei der man den String ohne Pointer übergeben kann
Prototype a_string(a.p-ascii)
Define a2.a_string = @a()

a2("hi")
a(@"hi")
Debug "Vergleichswert:"
Debug @"hi"
Und bezüglich deines "ShellExecute": MSDN - ShellExecute function
Da siehst du auch, dass die API in Wirklichkeit Pointer erwartet. Purebasic macht es eben nur etwas komfortabler für den Nutzer, dass man nicht extra ein @ davor schreiben muss.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: API string und zeiger

Beitrag von ts-soft »

PureBasic Libs / Userlibs unterstützen noch den Datentyp Any. Da wird alles als Pointer übergeben.
Da dieser Datentyp aber oftmals auch zu fehlern führt, wurde er aus einigen Befehlen, wie z.B. die
ganzen CallFunction... befehle wieder entfernt.

In PureBasic Sourcecode gab es diesen Typen aber noch nie! Da wirste Dich wohl entscheiden müssen,
String oder Pointer :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Re: API string und zeiger

Beitrag von _JON_ »

Ok, ich habe mich entschieden. Nur noch Pointer ab jetzt.
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: API string und zeiger

Beitrag von NicTheQuick »

Der Vorteil an Pointern ist, dass man schneller auf dem String arbeiten kann, z.B. parsen oder ähnliches. Der Nachteil an Pointern ist, dass jede Änderung im String ihn auch nach außen hin ändert.
Allerdings können so auch allerhand lustige Dinge geschehen wie zum Beispiel das hier:

Code: Alles auswählen

Procedure shiftRight(*text.Character)
	Protected *c.Character = *text + SizeOf(Character)
	Protected temp.c = *text\c
	While *c\c
		Swap temp, *c\c
		*c + SizeOf(Character)
	Wend
	*text\c = temp
EndProcedure

Debug "Hallo"
shiftRight(@"Hallo")
Debug "Hallo"
shiftRight(@"Hallo")
Debug "Hallo"
shiftRight(@"Hallo")
Debug "Hallo"
shiftRight(@"Hallo")
Debug "Hallo"
shiftRight(@"Hallo")
Debug "Hallo"
Wie man sieht steht da mehrmals ein 'Debug "Hallo"'. Dennoch wird jedes mal etwas anderes ausgegeben. Wenn ein konstanter String wie "Hallo" mehrmals in einem PureBasic-Quellcode vorkommt, dann wird er trotzdem nur einmal im ASM-Code gespeichert, und zwar einfach nur aus platzsparenden Gründen. Wenn man dieses String jetzt aber per Pointer manipuliert, ändert er sich automatisch überall.

Also immer dran denken. Bei Pointern ist Vorsicht geboten.
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: API string und zeiger

Beitrag von Chimorin »

Wie? Was? Ist es bei diesem "Feature" egal, wie weit die hardcoded Strings voneinander entfernt sind?
Bild

- formerly known as Bananenfreak -
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: API string und zeiger

Beitrag von NicTheQuick »

Hm, keine Ahnung. Müsste man wohl ausprobieren. :D
Mir ist es eben auch erst wieder aus Versehen aufgefallen, aber im Grunde ist es schon immer so gewesen und ich bin nur nochmal daran erinnert worden.
Antworten