• Welcome to Jose's Read Only Forum 2023.
 

how to simulate FreeBasic strings in PowerBasic

Started by Marc Pons, December 18, 2012, 01:23:10 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Marc Pons

I want to create  Freebasic string type in Powerbasic  for Powerbasic Dll sending or receving FreeBasic string type. 
In freebasic I can manage BSTR type conversion, but in PowerBasic ?

I  tried like that :

TYPE FBstring
     data1          as stringz ptr 
     len1            as long
     size1             as long 
END TYPE

It seems not exact , I nether get the len or size , the data is not always good either .
Any advice ?

thanks , Marc

Patrice Terrier

It is better to use ASCIIZ string (null terminated).

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Eros Olmi

#2

/** Structure containing information about a specific string.
*
* This structure hols all informations about a specific string. This is
* required to allow BASIC-style strings that may contain NUL characters.
*/
typedef struct _FBSTRING {
  char     *data;  /**< pointer to the real string data */
  int      len;  /**< String length. */
  int      size;  /**< Size of allocated memory block. */
} FBSTRING;


Not having exact info about what you are trying to do, I will show I I pass a BSTR FreeBasic string from FreeBasic to a PowerBasic DLL BYREF to get back data.

In a PowerBasic DLL I have the following function (here below the FreeBasic DECLARE code)
DECLARE FUNCTION  thinBasic_ParseString  ALIAS "thinBasic_ParseString"  (BYREF Result As BSTR) AS long

In a FreeBasic source I have the following function that declare a BSTR string, pass it BYREF to PowerBasic function and get back result.
Than result is casted to a FreeBasic string to print
sub Exec_FBGFX_Print()
Dim ParensPresent As Long
Dim sBSTR       As BSTR

'---Check if open parens is present
ParensPresent = thinBasic_CheckOpenParens_Optional

thinBasic_ParseString(sBSTR)

Print *cast( Zstring Ptr, sBSTR )

If ParensPresent = TB_TRUE Then thinBasic_CheckCloseParens_Mandatory

End sub


Hope it can help
Eros
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Eros Olmi

At this address I found two functions can help: http://freebasic.narod.ru/comdll.html

#DEFINE _UNICODE

'convert string to bstr
'please follow with sysfreestring(bstr) after use to avoid memory leak
Function StringToBSTR(cnv_string As String) As BSTR
    Dim sb As BSTR
    Dim As Integer n
    n = (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cnv_string, -1, NULL, 0))-1
    sb=SysAllocStringLen(sb,n)
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cnv_string, -1, sb, n)
    Return sb
End Function

Function BstrToStr(Byval szW As BSTR ) As String
    Static szA As ZString*256
    If szW=NULL Then Return ""
    WideCharToMultiByte(CP_ACP,0,SzW,-1,SzA,256,NULL,NULL)
    Return szA
End Function
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Eros Olmi

thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Marc Pons

 ;D
Thanks Patrice & Eros
I will experiment your proposals

Marc

Marc Pons

After tests , here is my conclusion : to "simulate" in powerbasic dll a FreeBasic string , no probleme !


Here under the 4 cases, I tested

' IN POWERBASIC SIDE

Type Fbstring
     Data1    As Stringz Ptr    'Pointer To The Real String Data
     Len1     As Long          'String Length
    Size1      As Long          'Size Of Allocated Memory Block
End Type
  'Memory Block, Multiple Of 36; When Len1 <33 Size1=36   ; When Len1 < 69 Size=72 .....
 
' From  FreeBasic vision : Send String ByRef , Receive BSTR  
Function TestFb1 Alias "TestFb1"(Mes1 As Fbstring)Export As String
   Local Ptt1 As Stringz Ptr
   Local Len2 As Long, Size2 As Long, Ret As String,Arriv As String
   
   Ptt1=Mes1.Data1
   Arriv=@Ptt1
   Len2=Mes1.Len1
   Size2=Mes1.Size1
   ? Arriv & Chr$(10) & Str$(Len2)  & Chr$(10) & Str$(Size2)
   Ret=Arriv & " Et Retour De La Dll"
   Function = Ret
   
End Function

' From  FreeBasic vision : Send String ByRef , Receive String
Function TestFb2 Alias "TestFb2"(Mes1 As Fbstring)Export As Dword
   Local Ptt1 As Stringz Ptr
   Local Len2 As Long, Size2 As Long, Ret As String,Arriv As String,Interm As String
              Local  Fb1 As Fbstring
   Ptt1=Mes1.Data1

   Arriv=@Ptt1
   Len2=Mes1.Len1
   Size2=Mes1.Size1
   ? Arriv & Chr$(10) & Str$(Len2)  & Chr$(10) & Str$(Size2)
   Ret=Arriv & " Et Retour De La Dll"
   Size2 = Int((Len(Ret)+3)/36) * 36 +36
   
   Fb1.Data1= Strptr(Ret)
   Fb1.Len1=Len(Ret)
   Fb1.Size1=Size2
   Function = Varptr(Fb1)
End Function

' From  FreeBasic vision : Send String ByVal , Receive BSTR
Function TestFb3 Alias "TestFb3"(Byval Mes1 As Stringz Ptr)Export As String 
   Local Len2 As Long, Ret As String, Arriv As String
   
   Arriv=@Mes1
   Len2=Len(Arriv)
   Ret=Left$(Arriv,Len2)
   ? Ret & Chr$(10) & Str$(Len2) 
   Ret=Ret & " Et Retour De La Dll"
   Function = Ret
End Function

' From  FreeBasic vision : Send String ByVal , Receive String    
Function TestFb4 Alias "TestFb4"(Byval Mes1 As Stringz Ptr)Export As Dword
   Local Len2 As Long, S2 As Long, Ret As String, Arriv As String
              Local  Fb1 As Fbstring ,Interm As String
   
   Arriv=@Mes1
   Len2=Len(Arriv)
   Ret=Left$(Arriv,Len2)
   ? Ret & Chr$(10) & Str$(Len2) 
   Ret=Ret & " Et Retour De La Dll"
   S2 = Int((Len(Ret)+3)/36) * 36 +36
   
   Fb1.Data1= Strptr(Ret)
   Fb1.Len1=Len(Ret)
   Fb1.Size1=S2
   Function = Varptr(Fb1)
End Function

And from the declarations in FreeBasic :

' IN FREEBASIC SIDE

Extern "Windows-MS" Lib "fbstring"  ' fbstring for name of Dll
Declare Function tt1 Alias "TestFb1"( ByRef mes1 As String) As BSTR
Declare Function tt2 Alias "TestFb2"( ByRef mes1 As String) As String

Declare Function tt3 Alias "TestFb3"( ByVal mes1 As String) As BSTR
Declare Function tt4 Alias "TestFb4"( ByVal mes1 As String) As String
End Extern


Hope, it can help , Marc

Theo Gottwald

The string engine in PB ist the part where the hidden power is.
I have not seen this anywhere else.
If you really manage to put something like that into FB it would make it significantly stronger.
Emulations and simulations are not of interest because the Power is just that it works so easy in PB.

Marc Pons

Theo,

First ,
       <<If you really manage to put something like that into FB it would make it significantly stronger.>>

my answer : yes it works

Second
       <<Emulations and simulations are not of interest because the Power is just that it works so easy in PB.>>
my answer : the need, is to share information both sides :with Dll in PowerBasic and main program in FreeBasic or vice-versa
the most difficult to share are strings. 

I hope it could help other people here.
Marc

Theo Gottwald

Honestly ... i did not yet have taken a really close look on FB.
At this time i can only say that all tries from PureBasic to make something that can compete with PB strings have failed until today.
Strings have been the way to store informations since the good old ATARI 400 Basic.
For me, they just save time.

Marc Pons

Theo

Truthfully, I don't understand your last posts :

Why are you speaking about PureBasic ? Who told about competing with Pb  strings?
what intention about your string history and ATARI digression ?

My topic only intend to ask/give some points on collaborative way, on how to manage the FreeBasic strings into PowerBasic to ease the way PowerBasic/freebasic can share strings into their own format.
I have seen the helpfull Eros posts to manage PowerBasic strings ( BSTR) in FreeBasic  and i thanks him for that but until now i haven't seen how to manage the FreeBasic strings in PowerBasic.
And if you want to use an existing dll done for FreeBasic you will face the difficulty on working with these strings
that's all.
Marc

Eros Olmi

Here another interesting source.
It shows how to create a COM Server manually by programming all the necessary components.

Inside (3rd frame) you will find 2 interesting functions that can help: StringToBSTR and BstrToStr
I think the method can be replicated to convert from FB String into PB String (which is a BSTR)


'convert string to bstr
'please follow with sysfreestring(bstr) after use to avoid memory leak
Function StringToBSTR(cnv_string As String) As BSTR
    Dim sb As BSTR
    Dim As Integer n
    n = (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cnv_string, -1, NULL, 0))-1
    sb=SysAllocStringLen(sb,n)
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cnv_string, -1, sb, n)
    Return sb
End Function

Function BstrToStr(Byval szW As BSTR ) As String
   Static szA As ZString*256
   If szW=NULL Then Return ""
   WideCharToMultiByte(CP_ACP,0,SzW,-1,SzA,256,NULL,NULL)
   Return szA
End Function
thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Marc Pons

To conclude : 2 PowerBasic Functions to convert From/to FreeBasic strings

Type FBstring
     Data1     As Stringz Ptr        'Pointer To The Real String Data
     Len1      As Long                 'String Length
     Size1      As Long                'Size Of Allocated Memory Block
End Type
  'Memory Block, Multiple of 36; if Len1<33 Size1=36   ; if  32< Len1 < 69 Size=72 .....

'   to convert received strings from FreeBasic ( passed ByRef)
Function FBstringToPBstring(ByRef Mes1FB As FBstring) As String      'receive adress descriptor of FB string
   Local Ptt1 As Stringz Ptr
   
   Ptt1=Mes1FB.Data1
   Function = @Ptt1

END FUNCTION


'   to convert strings to send to FreeBasic
Function PBstringToFBstring(ByRef Mes2PB As string) As Dword      ' send adress descriptor of FB string
   Local  FB1 As FBstring

   Fb1.Data1 = Strptr(Mes2PB)
   Fb1.Len1 =Len(Mes2PB)
   Fb1.Size1 = Int((Len(Mes2PB)+3)/36) * 36 + 36
   Function = Varptr(FB1)
   
END FUNCTION