Illegal specification

General FreeBASIC programming questions.
deltarho[1859]
Posts: 1014
Joined: Jan 02, 2017 0:34
Location: UK

Re: Illegal specification

Postby deltarho[1859] » Feb 19, 2018 0:26

caseih wrote:So if I'm understanding correctly, deltarho[1859] should just leave his PB dll using dynamic strings, and then communicate with that dll using the BSTR functions the windows API provides, correct?

Josep Roca wrote:It is a way to do it.

Don't forget that I have access to both compilers so I have another degree of freedom.
srvaldez
Posts: 1514
Joined: Sep 25, 2005 21:54

Re: Illegal specification

Postby srvaldez » Feb 19, 2018 3:54

my thought is to use PB ASCIIZ strings.
deltarho[1859]
Posts: 1014
Joined: Jan 02, 2017 0:34
Location: UK

Re: Illegal specification

Postby deltarho[1859] » Feb 19, 2018 6:43

If I used, for example

Code: Select all

AES( AES128, "Address.txt", "Password", 0 )

where PB was expecting the 2nd and 3rd parameter to be PB dynamic strings ByVal then I got into trouble.

Returned PB's dll to its former glory ie ByVal As String

With this

Code: Select all

#include once "win/ole2.bi"
 
Function StrToBSTR( FB_String As String) As BSTR
  Return  SysAllocStringByteLen( FB_String, Len(FB_String) )
End Function
 
' Get PB's library

Dim AS BSTR A0, A1, P
A0 = StrToBSTR("Address.txt")
A1 = StrToBSTR("Address.txt.aes")
P = StrToBSTR("Password")

AES( AES128, A0, P, 0)
Print "Wait"
Sleep
AES( AES128, A1, P, 0 )

SysFreeString(A0)
SysFreeString(A1)
SysFreeString(P)

Print "Done"
Sleep

I saw Address.txt.aes created. On the Wait I deleted Address.txt and pressed Enter. I then saw Address.txt being created and it was the same as the original Address.txt.

So I am now using PB's library as originally written and in FB all we need do is use StrToBSTR( <string> ) instead of <string>.

Thanks José for SysAllocStringByteLen.

Added: The better solution for me is the first one where PB's library is re-compiled so that we can write FB code as normal. The second solution comes into it's own where we cannot re-compile a library expecting BSTR strings.
caseih
Posts: 1161
Joined: Feb 26, 2007 5:32

Re: Illegal specification

Postby caseih » Feb 19, 2018 16:38

So help me understand BSTR, as I'm curious about it. José, are you saying that PB's native string type (dynamic string) is BSTR? As near as I can tell BSTR is just a pointer to a bunch of OLECHARs (Essentially WChars). Where is the length stored? Or is it? A brief search and looking at the header files suggests BSTR is very similar to ZString, although with 16-bit wide characters.

In my mind, FB's ZString is not a good option here, especially for file names, unless you use ASCII, UTF-8, or some other byte encoding, which isn't a natural fit on Windows as your PB function would have to decode whatever byte encoding your Zstring used, and re-encode to UTF-16 before calling any Win32 api. In my mind, BSTR is your bettery option here, since it's natively UTF-16 unicode. But you will have to consider how your FB strings (and literal strings) are converted to BSTR and what encoding the conversion function is expecting (ASCII, UTF-8, or something else).

EDIT: removed ansi vs unicode stuff
Last edited by caseih on Feb 19, 2018 18:49, edited 1 time in total.
Josep Roca
Posts: 244
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Illegal specification

Postby Josep Roca » Feb 19, 2018 17:33

> are you saying that PB's native string type (dynamic string) is BSTR?

Yes, both STRING (ansi strings) and WSTRING (unicode strings). The PB equivalent type for FB's WSTRING is WSTRINGZ. A BSTR is a data type implemented in Windows by the COM library, so what PB does is to wrap it to allow to use it transparently, without having to call directly the Windows API functions SysAllocString, etc.

A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator.

Length prefix
A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string. This value does not include the terminator.

Data string
A string of Unicode characters. May contain multiple embedded null characters.

Note: If allocated using the API function SysAllocStringByteLen it will contain an ansi string.

Terminator
A NULL (0x0000) WCHAR.

So a BSTR carries its length with it.
caseih
Posts: 1161
Joined: Feb 26, 2007 5:32

Re: Illegal specification

Postby caseih » Feb 19, 2018 18:47

Yes but what I was asking is about the struct that BSTR sits in. Turns out that BSTR does have a struct of sorts, but you never see it. I found a good blog entry on MSDN that explains that the length field is in memory right before the first byte of the actual string itself. The blog entry also states that BSTR strings are always a fixed length, so you can use null bytes in them.

What's confusing to me is that sometimes a BSTR can contain wide characters, and sometimes narrow?
Josep Roca
Posts: 244
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Illegal specification

Postby Josep Roca » Feb 19, 2018 19:52

What the buffer contains are bytes. It is up to you to treat it as if it contains single bytes (ansi or binary) or double bytes (unicode). There is not a fixed structure. Windows allocates 4 bytes for the size, n bytes for the content and 2 bytes for the ending double null, and returns a pointer to the content.
deltarho[1859]
Posts: 1014
Joined: Jan 02, 2017 0:34
Location: UK

Re: Illegal specification

Postby deltarho[1859] » Feb 19, 2018 20:06

I like to think of unicode as a pint glass which can accommodate half pint or full pint measures. Ansi, on the other hand, is a half pint glass which cannot accommodate a full pint. Having said that I cannot recommend going into a bar and asking for a unicode of Guinness. <smile>

Return to “General”

Who is online

Users browsing this forum: No registered users and 2 guests