IT-Berater: Theo Gottwald (IT-Consultant) > Freebasic

FreeBASIC CWstr

(1/45) > >>

Juergen Kuehlwein:
Well José i would have preferred to ask these questions here http://www.planetsquires.com/protect/forum/index.php?topic=4049.0, but registration is not possible as it seems.

First of all, congratulations for what you have done with WinFBX! I´m most interested in the Unicode string part (CWstr, CBstr) for FreeBASIC.


1.) My first question is, why two versions of wide strings? I read a post, where you stated you are using CBstr for COM - is CWstr not working for COM ?


2.) "sptr" and "vptr" do the same thing, i would have expected "sptr" to return a pointer to the data and "vptr" to return a pointer to the type - just like "strptr" and "varptr". Is this by intention or by error ?


3.) There is a problem with "LEFT", "RIGHT" and some other statements in FreeBASIC, maybe i found a solution for this.

--- Code: ---PRIVATE FUNCTION Left OVERLOAD (BYREF cws AS CWSTR, BYVAL nChars AS INTEGER) byref as wstring

static s as cwstr

   s = LEFT(**cws, nChars)
   RETURN *cast(wstring ptr, *s)


END FUNCTION

--- End code ---

Implementing this you may use "LEFT" (and others) in regular code just as usual (without the need of "**"). Do you see any problems here ?


4.) To my surprise the following code:

--- Code: ---himage = loadimage(hinst, d, %IMAGE_BITMAP, 0, 0, %LR_DEFAULTCOLOR)

--- End code ---
works for "DIM d AS STRING" AND for "DIM d AS CWstr" - how could that happen ?

"d" (the bitmaps resource name - STRING or CWstr) is passed: BYVAL NAME AS LPCSTR. I understand how this works for a STRING, but i don´t understand how this could work for a CWstr - but it definitely does (32 and 64 bit) while

--- Code: ---himage = loadimage(hinst, STRPTR(d), %IMAGE_BITMAP, 0, 0, %LR_DEFAULTCOLOR)

--- End code ---
works for a string, but not for a CWstr.


5.) "STRPTR" doesn´t work for a CWstr at all (compiler error), you must use "STRPTR(**d) or just *d, how could we make it accept "STRPTR(d)" ?


6.) having the exact same syntax for STRING (ANSI) and CWstr (Unicode) would make it possible to avoid multiple

--- Code: ---#ifdef %unicode   
dim   d AS CWstr
#ELSE
dim   d AS STRING
#ENDIF

--- End code ---
and to have one

--- Code: ---#ifdef %unicode   
#define dstr CWstr
#ELSE
#define dstr STRING
#ENDIF

... and then ...

DIM d AS dstr

--- End code ---
where "dstr" stands for "dynamic string" and could be used for ANSI and Unicode - if they only shared the same syntax...


Eager to hear your explanations and thoughts,


JK

José Roca:

--- Quote ---Well José i would have preferred to ask these questions here http://www.planetsquires.com/protect/forum/index.php?topic=4049.0, but registration is not possible as it seems.

--- End quote ---

See the "READ ME FIRST" post: http://www.planetsquires.com/protect/forum/index.php?topic=3777.0


--- Quote ---Registrations are disabled.

You MUST email support@planetsquires.com and request to be added as a member.

Please provide a "username" or "handle" when you request registration.

--- End quote ---

José Roca:

--- Quote ---1.) My first question is, why two versions of wide strings? I read a post, where you stated you are using CBstr for COM - is CWstr not working for COM ?

--- End quote ---

COM uses BSTRings, that are allocated and freed by the Windows OLE library. A CWSTR is a class with an underlying double null terminated buffer that is allocated, manipulated and freed by the class, using string build techniques. The advantage of using CWSTR over CBSTR for general purpose is that CWSTR is much faster.

A BSTR carries its length with it, but a pointer to a CWSTR not. Therefore, it is not suitable for use with COM.

José Roca:

--- Quote ---2.) "sptr" and "vptr" do the same thing, i would have expected "sptr" to return a pointer to the data and "vptr" to return a pointer to the type - just like "strptr" and "varptr". Is this by intention or by error ?

--- End quote ---

They don't do the same thing. sptr returns a pointer to the CWSTR buffer variable and vptr to the string data. You can use * or ** instead. I have implemented sptr and vptr for those that are not comfortable using * or **. I ended having to use ** instead of @ because, otherwise, I could not use @ to get the address of the class.

However, with CBSTR, vptr is important to be used with OUT parameters:


--- Code: ---' ========================================================================================
' * Frees the underlying BSTR and returns the BSTR pointer.
' To pass the underlying BSTR to an OUT BYVAL BSTR PTR parameter.
' If we pass a CBSTR to a function with an OUT BSTR parameter without first freeing it
' we will have a memory leak.
' ========================================================================================
PRIVATE FUNCTION CBStr.vptr () AS AFX_BSTR PTR
   CBSTR_DP("CBSTR vptr")
   IF m_bstr THEN
      SysFreeString(m_bstr)
      m_bstr = NULL
   END IF
   RETURN @m_bstr
END FUNCTION
' ========================================================================================

--- End code ---


José Roca:

--- Quote ---3.) There is a problem with "LEFT", "RIGHT" and some other statements in FreeBASIC, maybe i found a solution for this.

--- End quote ---

I'm already using


--- Code: ---' ========================================================================================
PRIVATE FUNCTION Left OVERLOAD (BYREF cws AS CWSTR, BYVAL nChars AS INTEGER) AS CWSTR
   RETURN LEFT(*cast(WSTRING PTR, cws.m_pBuffer), nChars)
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION Right OVERLOAD (BYREF cws AS CWSTR, BYVAL nChars AS INTEGER) AS CWSTR
   RETURN RIGHT(*cast(WSTRING PTR, cws.m_pBuffer), nChars)
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION Val OVERLOAD (BYREF cws AS CWSTR) AS DOUBLE
   RETURN .VAL(*cast(WSTRING PTR, cws.m_pBuffer))
END FUNCTION
' ========================================================================================

--- End code ---

You can use CWSTR as if it was a native data type, even with arrays. Currently, it works with all the intrinsic FreeBasic functions and operators except MID when used as a statement. Something like MID(cws, 2, 1) = "x" compiles but does not change the contents of the dynamic unicode string. MID(cws.wstr, 2, 1) = "x" or MID(**cws, 2, 1) = "x" works. This is because when simply passing cws, FreeBasic creates a temporary WSTRING and changes the content of that temporary string.

Navigation

[0] Message Index

[#] Next page

Go to full version