The SysAlloc APIs are specialized versions of the more generic memory APIs,
so I'd speculate they might be slower. Probably, it doesn't make a great
deal of difference but, when in doubt, try it out.
I don't mean to recommend HeapAlloc in particular. Windows offers a variety
of memory APIs. You might search for some of the previous messages on this
subject.
------------------
Tom Hanlin
PowerBASIC Staff
Announcement
Collapse
No announcement yet.
What API to use to make PB string compatible dynamic string?
Collapse
X
-
Btw Tom,
Can you recommend SysAlloc.. above the GetProcessHeap()/HeapAlloc combination?
I expect SysAlloc to be faster.
Then i would prob. use peek$ to access it..
Thanks,
------------------
http://www.hellobasic.com
Leave a comment:
-
-
Variable-length strings are inherently inefficient in numerous respects, and it's
really not a good plan to try to fool the compiler into thinking your strings are
its strings. This approach does not seem appropriate to the task at hand.
It would almost certainly be safer, faster, and easier if you just did it using
BYTE pointers with HeapAlloc, and wrote your own byte-based search routine to
replace the former use of INSTR.
------------------
Tom Hanlin
PowerBASIC Staff
Leave a comment:
-
Leave a comment:
-
Hi Edwin
you should use SysAllocStringByteLen not SysAllocStringLen
which is unicode and use SysStringLen() although you'll
probably be okay if you use LEN()
Cheers
Florent
------------------
Leave a comment:
-
Thanks,
The freeing was just an example, i declared it wrong anyway.
Let's forget that one..
The following code becomes importaint to me.
See the original length, it's 2x the size.
Just don't understand this part.
Code:#Compile Exe #include "win32api.inc" Function WinMain( ByVal hCurInstance As Long, _ ByVal hPrevInstance As Long, _ lpszCmdLine As Asciiz Ptr, _ ByVal nCmdShow As Long ) As Long Dim sData As String Dim pAddr As Long Ptr Dim Lng As Long Dim T As String Ptr sData = Repeat$( 1, "12345678" ) pAddr = SysAllocStringLen( ByVal StrPtr( sData ), Len( sData ) ) '// Seems to be a must.. Lng = pAddr T = VarPtr( Lng ) '// Check length of SysAllocStringLen() and original Len of sData.. MsgBox Format$( Len( @T ) ) & ", " & Format$( Len( sData ) ) & $CRLF _ & "'" & @T & "'" '// Refill using PB.. @T = "1234" '// Check out lengths again.. MsgBox Format$( Len( @T ) ) & ", '" & @T & "'" SysFreeString ByVal pAddr End Function
http://www.hellobasic.com
Leave a comment:
-
SysAllocStringByteLen is not Unicode...
In order to check that a string has been effectively
freed you should check GetLastError() after each call
to SysFreeString() - a non-zeo return value indicates
an error. Use SysStringLen() to find the length of the
string.
It's my understanding that strings freed are marked for
deletion but not immediately freed (they are "lazily" collected).
You're asking for trouble when addressing freed strings although
the trouble may not be immediately apparent. Set the string
pointer to NULL after freeing it - it'll help to avoid
errors.
Cheers
Florent
------------------
Leave a comment:
-
Already found out that this writes in the wrong mem
Don't use it..
The SysAlloc.. calls are unicode, PB doen't seem to use it that way.
There is a conflict in string length that way.
The original API declare will take 2x the size.
A string pointer set will show this until you use the string poiter to set new data.
Then Len() will work ok.
It becomes a bit weird now.
It certainly would help me if i get this to work.
------------------
http://www.hellobasic.com
Leave a comment:
-
Semen,
This is the way we use it.
At the end it get's to much items, the search becomes to slow.
We use objectnames (e.g. "TEXT1") to find the data.
PB:
Can i use the code below,
It seems the String ptr creates it's own memory address.
However, i don't know when or how to destroy the memory.
There should be a crash in the following code but does not.
Code:#Compile Exe #include "win32api.inc" Function WinMain( ByVal hCurInstance As Long, _ ByVal hPrevInstance As Long, _ lpszCmdLine As Asciiz Ptr, _ ByVal nCmdShow As Long ) As Long Dim L As Long Dim T As String Ptr L = VarPtr( L ) T = L @T = "1345sdfyghbfghn" '?????????????????????? SysFreeString ByVal L SysFreeString L SysFreeString ByVal T SysFreeString ByVal VarPtr( @T ) MsgBox @T End Function
http://www.hellobasic.com
Leave a comment:
-
Edwin --
What about this organization of multidimensional array (w/o API) ?
Code:#Compile Exe #Dim All #Register None #Include "WIN32API.INC" Function PbMain ' %n - maximum strings in all files %n = 5 %nf = 3 ' maximum records in one file Dim s(%n - 1) As String ' Strings Dim r(%n - 1) As Long ' File id Dim v(%nf - 1) As Long ' for VarPtr '============== Fill strings ============= s(0) = "File 1, Record 1" : r(0) = 1 s(1) = "File 2, Record 1" : r(1) = 2 s(2) = "File 1, Record 2" : r(2) = 1 s(3) = "File 1, Record 3" : r(3) = 1 s(4) = "File 2, Record 2" : r(4) = 2 '============ Create "array" from single file ==== Dim i As Long, k As Long, f As Long For f = 1 To 2 k = 0 For i = 0 To %n - 1 If r(i) = f Then v(k) = StrPtr(s(i)): Incr k Next If k > 0 Then ReDim ss(k - 1) As String At VarPtr(v(0)) For i = 0 To k - 1 MsgBox ss(i),, "Array" + Str$(f) Next End If Next End Function
E-MAIL: [email protected]
Leave a comment:
-
For situation 1 we have a single array where we use array scan.
This array is a simple long containing a crc of another dynamic string array containing the real name of the object.
The CRC is found in the 'long' array and it checks the requested objecname.
this is because the CRC can be added multiple times plus in this older situation, the file index needs to be check too.
The older system handles multiple files in 'one' array (where at the end 4 arrays are used to manage this all)
Complex?
I can do this with api but then i need peek and poke what i dislike.
------------------
http://www.hellobasic.com
Leave a comment:
-
1) I need a multidimensional array where the second array must be flexible
2) I need a multidimensional String array where the second array must be flexible
Let's speak about situation 2 only:
Global Files() As String
(f = 1 to nn, depends on opened files)
x = nn objects for that file
this can be less or more than in Files( 2...
ReDim Files( 1 to f, 1 To x )
Since this is not possible i'm gonna use API's
A heapalloc to allocate a string ptr array to solve the Files( 1 to f, part
The address will be stored in a single array.
The data should be a dynamic string
It's length is variable per element (1 byte to 200k etc..)
I wanted to use a string ptr to explore the memory address using instr etc..
So i would have to copy the data over and over.
This is a time critical procedure and must be very fast.
We already have it running where all 'files' are stored in 1 string array.
After 10000 objects the search is slow.
10000 objects is fine but not if multiple files are adding another 10000 objects to it.
We need to break it up.
(PS, there's no way i rewrite these file systems, it's implemented for 1000's of users already.)
This is a weird situation because of the dynamic range required for the second entry of the m. array.
------------------
http://www.hellobasic.com
Leave a comment:
-
As has been pointed out, PB uses SysAllocStringByteLen in creating strings.
However, as usual, it's (1) a bad idea to try to fool the compiler, and (2)
you don't generally gain anything by trying.
It sounds to me like your best bet here is to PEEK$ and POKE$ the data. If
you would like to explain what you need to do in more detail, though,
perhaps a better solution will offer itself.
------------------
Tom Hanlin
PowerBASIC Staff
Leave a comment:
-
Semen,
I have not planned to use any PB code to redim the original contents.
This will be API/OLE too.
The memory will be destroyed and rebuild.
------------------
http://www.hellobasic.com
Leave a comment:
-
i REALLY want the PB strings.
Wich API/Method is PB using.
I simply can use my memory using HeapAlloc etc and add 4 bytes (long ) before the string data to simulate the OLE strings.
This is NOT safe for future windows versions.
I really need the original PB calls so that String Ptr can be used on them.
Jules, if i check the PB EXE's, i see the SysAllocStringByteLen() api calls.
I need confirmation on that.
In this case i need to create my own memory, for using it i would like to use PB's string pointer.
Peek$() will be my last resort.
------------------
http://www.hellobasic.com
Leave a comment:
-
It's not a problem to fool PB, if to use OLE functions (PB does the same).
Code:#Compile Exe #Dim All #Register None #Include "WIN32API.INC" Function PbMain ' Step 1 - Create Strings Dim x(2) As Local Long x(0) = SysAllocStringByteLen("Compile", 7) x(1) = SysAllocStringByteLen("Compile Exe", 11) x(2) = SysAllocStringByteLen("Dim", 3) ' Let's fool Pb ReDim s(2) As String At VarPtr(x(0)) MsgBox s(0) + $CRLF + s(1) + $CRLF + s(2) End Function
Of course, it's possible to create in memory OLE-similar strings (length of string, string as it is, zero).
But I am afraid re-allocate statements (a$ = ...)
------------------
E-MAIL: [email protected]
Leave a comment:
-
Edwin,
Look into these API's functions, they were handed to me by Florent Heyworth,
they are very interesting functions.
Code:SysAllocStringByteLen() SysFreeString()
Regards,
Jules
Leave a comment:
-
Well, if you want dynamic (variable length) strings, you will not be able to specify the address of the string data except by POKEing the data where you want it..
Your best bet might be what you've started - an array of STRING PTR which you create at a specific memory location with DIM AT.
What I do not understand is what API call returns an address but does not handle the allocation of the memory?
Which API call is this?
MCM
Leave a comment:
-
What API to use to make PB string compatible dynamic string?
I need to use the API (i think) to create a dynamic string but the address is fixed.
The memory area is created by a specific api call, an array with String ptrs will be used to access these strings.
I can not use asciiz.
Code:Global MyArray() As String Ptr '''' Redim MyArray( 1 to 1000 ) Dim pAddr As Dword pAddr = >> this is the problem, Malloc or sort of, don't know exactly.. MyArray( 1 ) = pAddr Dim PBString As String At MyArray( 1 ) (Or string ptr if necessary) Msgbox PBString
------------------
http://www.hellobasic.comTags: None
Leave a comment: