• Welcome to PlanetSquires Forums.
 

Strings in FreeBASIC

Started by Paul Squires, August 25, 2015, 09:11:16 AM

Previous topic - Next topic

Paul Squires

Quote from: Jose Roca on August 25, 2015, 09:35:26 PM
Since the target is a CBStr, you have to use


Dim bs1 As CBStr = "Test string 1"
Dim bs2 As CBStr = "Test string 2"
Dim bs3 As CBStr

bs3 = bs1 & bs2 
Print **bs3



Ahhhhhh, now that make sense. Thanks :)

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#31
There are many string functions in the API and the C runtimes than can be used with PB. It would be useful to collect information about them in order to not reinvent the wheel.

For example:

wsprintf function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms647550(v=vs.85).aspx
(many other string functions in that link)

Usage example:


DIM wszBuffer AS WSTRING * 260
DIM wszStr AS WSTRING * 260 = "Runing at (%i FPS) frames per second"
DIM fps AS INTEGER = 300
wsprintfW @wszBuffer, @wszStr, fps
print wszBuffer


José Roca

#32
I have removed the procedures MakeUpper and MakeLower because you can use instead


DIM bs AS CBStr = "Test string"
**bs = LCASE(**bs)   ' or UCASE
print **bs


I also have overloaded the operator LEN, so instead of bs.Len(bs) you can use


DIM bs AS CBStr = "Test string"
print LEN(bs)
-or-
print LEN(**bs)


José Roca

#33
I was wondering why the application crashed if I used something like


DIM bs AS CBStr
bs = UCASE("Ucase test")


and the reason is that FB creates temporary WSTRINGs, that don't have a descriptor, not real BSTRs.

Since BSTR is defined as WSTRING PTR in the FB headers, the same = operator was being called either if the passed string was a real OLE string handle or a temporary FB WSTRING.

So I have changed the code of the operator to detect if it is an OLE string or not:


' ========================================================================================
OPERATOR CBStr.Let (BYREF bstrHandle AS BSTR)
   IF bstrHandle = NULL THEN EXIT OPERATOR
   ' Free the current OLE string
   IF m_bstr THEN SysFreeString(m_bstr)
   ' Detect if the passed handle is an OLE string
   ' If it is an OLE string it must have a descriptor; otherwise, don't
   ' Get the length looking at the descriptor
   DIM res AS INTEGER = PEEK(DWORD, CAST(ANY PTR, bstrHandle) - 4) \ 2
   ' If the retrieved length if the same that the returned by LEN, then it must be an OLE string
   IF res = .LEN(*bstrHandle) THEN
      ' Attach the passed handle to the class
      m_bstr = bstrHandle
   ELSE
      ' Allocate an OLE string with the contents of the string pointer by bstrHandle
      m_bstr = SysAllocString(*bstrHandle)
   END IF
END OPERATOR
' ========================================================================================


Now we can do things like:


DIM bs AS CBStr = "Test"
bs = bs & " string"

--or--
bs = UCASE("Ucase test")

--or--
bs = "test " & "string"


etc.

As well as assigning real OLE strings:


FUNCTION Foo () AS BSTR
   FUNCTION = SysAllocString("Foo Test")
END FUNCTION

DIM bs AS CBStr = Foo

--or--
DIM bs AS CBStr
bs = Foo


If we want to use instrinsic FB functions with real OLE string handles, we have to deference it, since as I said, in the FB headers a BSTR is declared as a WSTRING pointer.


DIM bs AS CBStr
bs = UCASE(*Foo)


and if it is a variable of the type CBStr (my OLE string class), you have to use double indirection.


PRINT **bs


Problem:

Although bs = UCASE(*Foo) works, and also bs = *Foo & " --- " & *Foo, it should create a memory leak, since the OLE strings returned by the Foo function aren't being freed.

Therefore, we may need to do something like


DIM foo1 AS CBStr = Foo
DIM foo2 AS CBStr = Foo
DIM bs AS CBStr
bs = foo1 & " --- " & foo2
print **bs


It is the only caveat. Don't know if I can do something more.

Theo Gottwald

Wouldn't it be a good idea to talk to the FB-Compiler makers to get your work "hardcoded", Jose?
Freebasic is written ion Freebasic therefore it should be possible ...

José Roca

They don't need me to add support for OLE strings. It is not rocket science. What they lack is the will to do it, since it is a Windows only feature and they are Linuxers.