PDA

View Full Version : String format of Oxygen dll functions



MouseTrap
27-09-2009, 23:33
Im trying to get oxygen to work with Blitzmax and im running into some the problems.
The function "o2_basic' takes a parameter of 'string' but what kind of string?

If i pass in a 'C' string i get a crash. (on the call to o2_basic)
If i pass in a 'wide' string i also get a crash.
I tried passing a byte pointer directly from the strings bytes and also crash. (this may be the same just passing a c string )
The only thing that seems to work is just passing a normal blitzmax string, which i believe is an object handle.
but no matter what the contents of string I reviece the same "o2_error()" of:

; Ppush eax :call [ebx+1224] !! Unidentified instruction: ppush
; AFTER: ._stt

when calling o2_exec.

so what is that function expecting?
Thanks



Edit:
I dont know if this helps but Ive traced the crash with visual studio debugger.
Its 3 or 4 jumps inside the dll where the crash occurs. The code generated by Blitzmax looks like:


mov eax,_19 ;<- fixed string of o2 basic code
push eax
call _bbStringToCString
add esp,4
mov ebx,eax
push ebx
call dword [_bb_o2_basic]

Charles Pegge
28-09-2009, 09:45
Hi MouseTrap,

Oxygen uses BString for all its string params and string returns.

So O2_basic takes an ole bstring - this gives compatibility with thinBasic, PowerBasic and VB (using ascii rather than unicode).

Ole Bstrings are string pointers. the strings are always null terminated after the end of the string an also have a (hidden) dword containing the length in bytes immediately before the start of the string.

Can Blitz handle Bstrings directly?

Charles

MouseTrap
28-09-2009, 10:11
Can Blitz handle Bstrings directly?
No, but im trying this:


Function AllocBStr:Byte Ptr(s$)
Local buf:Byte Ptr = MemAlloc(s.Length*2+6)
Int Ptr(buf)[0] = s.Length*2 '// set size in 1st 4 bytes
buf :+ 4 'inc pointer 4
For Local idx:Int = 0 Until s.Length
Short Ptr(buf)[idx] = s[idx] '// copy string size of short!
Next
Short Ptr(buf)[s.Length]=$0000 '// add extra nulls
Return buf
End Function

I've declared the o2_basic function as accepting a byte pointer arg.
I no longer get any crashes or o2_error, But no matter what the contents of the o2h script the return of o2_exec is: '308516'
Setting eax before terminate has no effect on the return.

ErosOlmi
28-09-2009, 10:51
The attached is a representation of a BString.
Dynamic strings in thinBasic are all BString.

Mainly a BString is a 32 bit pointer to the attached memory representation.

MouseTrap
28-09-2009, 10:59
Interesting..
MS claims the data is unicode and finalized with 2 nulls.
Do you use a different format or does the picture just omit those?

http://msdn.microsoft.com/en-us/library/ms221069.aspx

ErosOlmi
28-09-2009, 11:08
A BString can contains any sequence of bytes limited only by OS memory handling (under 32 bit OS this limit is set to 2Gb)

So you can set a BString in UNICODE format or ANSI or you can put inside it any sequence of bytes. That's one of the beauty of BStrings: they can be used for whatever string or binary data it doesn't matter as far as you know what you are doing.

Another nice feature is that a BString pointer never change its memory position while the memory pointed by BString is dynamic and always change memory position every time the string is manipulated.

For standard text, thinBasic set BString as ANSI so exactly like you see in the picture. This is by design.

To transform it in UNICODE or from UNICODE to ANSI you can use UCODE$ (http://www.thinbasic.com/public/products/thinBasic/help/html/ucode%24.htm) or ACODE$ (http://www.thinbasic.com/public/products/thinBasic/help/html/acode%24.htm) depending to what other software you are interfacing.

Charles Pegge
28-09-2009, 12:24
MouseTrap,

I see that Blitz strings are standardised to Unicode. I have never tried Blitz but based on your function above, this is what I think you need to use.





#include once "windows.bi" 'equivalent
#include once "win/ole2.bi" 'equivalent


Function AllocBStr:Byte Ptr(s$)
Local buf:Byte Ptr = SysAllocStringBtyeLen(0, s.Length)
For Local idx:Int = 1 Until s.Length
Byte Ptr(buf)[idx-1] = s[idx] '// copy string as Ascii
Next
Return buf
End Function


.....

Sub FreeBStr(buf:Byte ptr)
SysFreeString (buf)
End Sub

ErosOlmi
28-09-2009, 12:49
API functions working on BString: http://msdn.microsoft.com/en-us/library/ms221105.aspx

Charles Pegge
28-09-2009, 15:55
I propose a way of changing the Oxygen string mode like this:

o2_mode n

where n is as follows

0 for ascii input and ascii pointer return (null terminated)

1 for ascii input and ascii pointer return (null terminated copy)

2 for unicode input and unicode pointer return (null terminated copy)

9 for BString ascii input and Bstring ascii return

10 for Bstring unicode input and Bstring unicode return.


This would apply to all strings except that it would not attempt to convert Executable binary strings to/from unicode!

The default mode as it is now will be 9 for Windows systems and probably 0 for Linux.

What do you think of this?

Charles

MouseTrap
28-09-2009, 18:52
Internally. blitzmax strings are unicode. but the user never sees any of it. all strings operations are ascii.
In the function posted above, you see that im reading the original string one byte at a time and writing the bstr buffer as a short to make unicode.
Mainly i just want know what O2h is expecting. bstr ascii?? bstr wide?

As for the o2_mode, an ascii mode would be nice, but only where the string receiver is responsible for making a local copy.
In general you should make external apps hosting o2h conform to your standard.
You could also have a utility function. like:

o2h_sConv(stringdata$,mode)
then consumers of the dll can use it optionally like:
o2h_basic( o2h_sConv(mystringz,1) )
eliminating string type checks on the dll side.

MouseTrap
28-09-2009, 18:54
For standard text, thinBasic set BString as ANSI so exactly like you see in the picture. This is by design.


So I believe my mistake is that im converting the string to unicode when making it a Bstr when it doesn't need to.
I did that based on the microsoft info i found online.

I'll mod the function and try again.

MouseTrap
28-09-2009, 19:50
It works!
The problem was making the data portion of the bstr unicode.
Thanks for the help!
now i'll see about hacking in function / variable pointers. :eusadance: