Seite 1 von 1

API string und zeiger

Verfasst: 17.02.2014 19:44
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

Re: API string und zeiger

Verfasst: 17.02.2014 19:53
von NicTheQuick
Darf man fragen wieso du das machen willst? Reicht es nicht aus nur das eine oder nur das andere zu übergeben?

Re: API string und zeiger

Verfasst: 17.02.2014 20:01
von _JON_
Eine Möglichkeit reicht natürlich, mich wunder nur das die vordeklarierten beides akzeptieren.

Re: API string und zeiger

Verfasst: 17.02.2014 20:35
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.

Re: API string und zeiger

Verfasst: 17.02.2014 20:42
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:

Re: API string und zeiger

Verfasst: 17.02.2014 20:55
von _JON_
Ok, ich habe mich entschieden. Nur noch Pointer ab jetzt.

Re: API string und zeiger

Verfasst: 17.02.2014 21:29
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.

Re: API string und zeiger

Verfasst: 17.02.2014 22:34
von Chimorin
Wie? Was? Ist es bei diesem "Feature" egal, wie weit die hardcoded Strings voneinander entfernt sind?

Re: API string und zeiger

Verfasst: 17.02.2014 22:52
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.