PDA

View Full Version : How to use asciiz inside a class?



efgee
03-09-2010, 01:46
Sorry to bother again... :)

How can a asciiz be used inside a class method?

Tried to return a string or a ascciiz but nothing seems to work.

Outside of a class - no problem...

Thanks
efgee

Below some generic test code I used:



' asciiz2string.bas
'
' how to use asciiz inside a class
' as oop
' efgee


; =======
; imports
; =======
dim as long kernel32 = LoadLibrary ("kernel32.dll")
bind kernel32 (
GetCommandLine GetCommandLineA : @0
GetModuleHandle GetModuleHandleA : @4
ExitProcess ExitProcess : @4
)


; =========
; constants
; =========
def true 1
def false 0
def fail -1


; =====
; CLASS
; =====
class test
private
static byref classcmdline as asciiz

public method SetCmdLine()
&this.classcmdline = GetCommandLine ()

; this prints out wrong!
print this.classcmdline
end method

public method GetCmdLine() as string
method = this.classcmdline
end method

end class


; =========
; variables
; =========
dim byref cmdline as asciiz, inst as long
dim commandline as string
dim p as test


; =====
; ENTRY
; =====

; normal way of doing it
&cmdline = GetCommandLine ()

; printing works
print cmdline

; get string value
commandline = cmdline

; check if the string type contains the
; correct value - works
print commandline

; ----------------------------
; now do the same with a class

; load the string into the asciiz class member
p.SetCmdLine()

; try to print it... crash!
print p.GetCmdLine() ; buggy!



freelibrary (kernel32)

ExitProcess ()

terminate

Charles Pegge
03-09-2010, 07:21
Hi Efgee,

Yes we have a pointer headache with Asciiz in methods. I was unable to fix it quickly so here is a solution using basic strings.

I have included a mini header with some kernel32 functions.



' asciiz2string.bas
'
' how to use asciiz inside a class
' as oop
' efgee / charles

basic

; =======
; imports
; =======

extern lib "KERNEL32.DLL"

declare FUNCTION AllocConsole ALIAS "AllocConsole" () AS LONG
declare FUNCTION GetCommandLine ALIAS "GetCommandLineA" () AS DWORD
declare FUNCTION GetStdHandle ALIAS "GetStdHandle" (BYVAL handle AS DWORD) AS DWORD
declare FUNCTION WriteConsole ALIAS "WriteConsoleA" (BYVAL hConsoleOutput AS DWORD, lpBuffer AS ASCIIZ, BYVAL nNumberOfCharsToWrite AS LONG, lpNumberOfCharsWritten AS LONG, BYVAL lpReserved AS LONG) AS LONG
declare FUNCTION ReadConsole ALIAS "ReadConsoleA" (BYVAL hConsoleInput AS DWORD, BYVAL lpBuffer AS DWORD, BYVAL nNumberOfCharsToRead AS LONG, lpNumberOfCharsRead AS LONG, pInputControl AS ANY) AS LONG
declare FUNCTION SetConsoleTitle ALIAS "SetConsoleTitleA" (lpConsoleTitle AS ASCIIZ) AS LONG

end extern


; =========
; constants
; =========
def true 1
def false 0
def fail -1


; =====
; CLASS
; =====
class test

private

static classcmdline as string

public

method SetCmdLine()
zstring ptr z
&z=getcommandline()
classcmdline=z
'print classcmdline
end method

method GetCmdLine() as string
method = classcmdline
end method
end class


; =========
; variables
; =========

dim p as test

p.SetCmdLine()

print p.GetCmdLine()



Charles

efgee
03-09-2010, 18:46
Hello Charles,
your example works fine.

It seems that the trick lies in having a asciiz variable locally (in a method) and storing it as string in a class variable (member) makes it accessible by another method.

Thank you for all your hard work.

efgee

Charles Pegge
03-09-2010, 19:54
Hi efgee,

Your original code should work but I have discovered a conspiracy of bugs preventing the correct referencing of an asciiz ptr member. I have caught two of them so far. One or two others remain hidden. I am glad you exposed the problem.

Charles

efgee
03-09-2010, 20:20
Anytime Charles, anytime... :D

BTW Thank you for creating such a capable compiler and sharing it with us.

Happy coding
efgee