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
It is better to use ASCIIZ string (null terminated).
...
/** 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
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
Some old discussions in thinBasic forum about BSTR in FreeBasic:
http://www.thinbasic.com/community/showthread.php?8173-FreeBasic-strings
;D
Thanks Patrice & Eros
I will experiment your proposals
Marc
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
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.
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
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.
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
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
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