Is there an alternative for the following:
Code:
'$Include: "crtdll.bi"
Type test
numstr As Integer
strs(0) As String Ptr ' Make dynamic array
End Type
Dim t1 As test, teststr() As String
Redim teststr(3) As String
teststr(0) = "Zero"
teststr(1) = "One"
teststr(2) = "Two"
teststr(3) = "Three"
t1.strs = calloc(3, 64) ' Allocate memory for pointer array
'Copy Data into string ptr
MemCpy(t1.strs, @teststr(0), 3*64)
Erase teststr
For i = 0 To 3
Print *t1.strs(i)
Next
I can success run the following routine without the prog crashing:
For i = 0 To 3
t1.strs(i) = testarr(i)
Print *t1.strs(i)
Next
But MemCpy crashes it. I need to copy the data into the actual pointer array. Any ideas?
you need to allocate space for each string first using some function like SPACE$ or STRING$
Do you have any code to see how that would work in my above example using the ptrs. I thought calloc handled memory allocation already.
sry (it's 4am in the morning) if I get smth wrong, but this works:
Code:
option explicit
'$include: 'win\crtdll.bi'
declare sub PokeStr ( byval Dest as any ptr, _
byref text as string, _
byval Lenght as integer = -1)
declare function PeekStr ( src as byte pointer ) as string
'-----------------------
dim test as string
dim testptr as any ptr
test = "This is a test string"
TestPtr=callocate(len(test))
PokeStr(TestPtr, test)
test = ""
test = PeekStr(TestPtr)
print Test
sleep
'-----------------------
sub PokeStr ( byval Dest as any ptr, _
byref text as string, _
byval Lenght as integer)
if Lenght = -1 then Lenght = len(text)
memcpy(Dest, sadd(text), Lenght)
end sub
function PeekStr ( src as byte pointer ) as string
PeekStr = *src
end function
The rest you can easily modify yourself, put a pointer into type, or smth, and use PokeStr & PeekStr for rading/writing strings to memory.
Also dynamic units in TYPE structure as far as I know is a unfixed bug, so don't rely on it mutch. I may be wrong though.
I guess you're right it's a bug. I hope it's implemented though.
FB var-len strings have descriptors as in QB/VB, a "dim s as string" allocates just the descriptor, string data is only (re)allocated when the string is assigned.
To get the real address of a var-len string, SADD() has to be used (as in QB), but yeah, you must allocate the data for it if using a pointer.
Btw, you can create var-len string fields on TYPE's, what isn't allowed in QB -- memory will leak if you don't do say mytype.myvarlenstring = "" at end of procs if mytype is local.
Ok. Now I'm just trying to get dynamic pointer arrays to work. Can you help me with this code.
Code:
' Pointer Arrays
' **************
' Alloc Array
Function AllocPtrArr(elem As Long, bytes As Long) As Any Ptr
AllocPtrArr = Allocate(elem * bytes)
End Function
Sub PutPtrArr(arr As Any Ptr, item As Any Ptr, elem As Long, numelem As Long, bytes As Long)
Dim temp() As Any Ptr, CopyMemory As Sub(ByVal pDst As Long, ByVal pSrc As Long, ByVal bytes As Long)
Redim temp(numelem) As Any Ptr
' CopyMemory = DLLFunc("kernel32.dll", "RTLMoveMemory")
' Fill temp array
MemCpy(temp(0), arr, numelem * bytes)
Print "Working"
temp(elem) = item
' Fill ptr array
MemCpy(arr, temp(0), numelem * bytes)
Erase temp
Print "Working"
End Sub
Function GetPtrArr(arr As Any Ptr, elem As Long, numelem As Long, bytes As Long) As Any
Dim temp() As Any Ptr, CopyMemory As Sub(ByVal pDst As Long,ByVal pSrc As Long, ByVal bytes As Long)
Redim temp(numelem) As Any Ptr
' CopyMemory = DLLFunc("kernel32.dll", "RTLMoveMemory")
' Fill temp array
MemCpy(temp(0), arr, numelem * bytes)
If temp(0) Then
GetPtrArr = temp(elem)
End If
End Function
What about this:
Code:
' Pointer Array Test
Type test
numstr(0) As Integer Ptr
strs(0) As String Ptr ' Make dynamic array
End Type
Dim t1 As test, teststr() As String * 64
Redim teststr(3) As String * 64
teststr(0) = "Zero"
teststr(1) = "One"
teststr(2) = "Two"
teststr(3) = "Three"
For i = 0 To 3
t1.numstr(i) = Allocate(4)
t1.strs(i) = Allocate(64) ' Allocate memory for pointer array
Next
' Copy Data into string ptr
For i = 0 To 3
*t1.numstr(i) = i * 64
*t1.strs(i) = teststr(i)
Next
Print "Works"
Erase teststr
For i = 0 To 3
Print *t1.numstr(i)
Print *t1.strs(i)
Next
Do Until Inkey$ <> ""
Loop
That won't work, simpler would be:
Code:
const MAXITEMS = 4
Type test
strs As string ptr
End Type
Dim t1 As test
dim p as string ptr
Redim teststr(3) As String * 64
teststr(0) = "Zero"
teststr(1) = "One"
teststr(2) = "Two"
teststr(3) = "Three"
t1.strs = callocate( len( string ) * MAXITEMS )
' Copy Data into string ptr
p = t1.strs
For i = 0 To MAXITEMS-1
*p = teststr(i) '' can't do t1.strs[i] while there's no pointer indexing
p = p + len( string )
Next
Print "Works"
Erase teststr
p = t1.strs
For i = 0 To MAXITEMS-1
Print *p '' same as above
p = p + len( string )
Next
sleep
Btw, version 0.09 will complain about len( STRING ), you will have to wait for the new version to compile the code above ;)
EDIT: it should be Callocate instead of Allocate, or else the string assign could try to free an invalid pointer, as Allocate won't fill the block allocated with 0's.
Thanks. Btw, when will pointer indexing be available?