Crash when using GROUP with BSTRING from `.inc`

I am trying to setup an interop between Clarion and NativeAoT Compiled DotNet project - but for some reason I am getting a nasty GPF by only declaring a variable based on a type from my INC

I am using BSTRING as I am wanting to pass the whole group by reference to my DotNet library - and BSTRING aligns with STRING in C# - If I open the Reproducible as Clarion 11 and Compile there’s no GPF at all, which is really weird - but perhaps it’s just bugged in Clarion 8 (Clarion)

The inc from the below reproducible looks as follows:

SomeError GROUP,TYPE
ErrorCode BSTRING
Description BSTRING
END

SomeResult GROUP,TYPE
State BSTRING
ActionUrl BSTRING
Value BSTRING
Error LIKE(SomeError)
END

The only thing needed for the crash is to add below line in a data declaration:

A LIKE(SomeResult)

And when I build and run the project I get an instant GPF

For the purpose of this I created a reproduction in the zip below - it’s Clarion 8 (but openend from the Clarion 11 Editor)
TestingGround.zip (970,0 KB)

EDITOR VERSIONS USED:
Clarion 8: 8.0.9759
Clarion 11: 11.1.13855

Seems the crash als happens if I define the group locally inside the procedure… is it really just broken in Clarion 8 to use BSTRINGs inside GROUPS?

(post deleted by author)

In my testing BSTRING in Group is also not well supported in Clarion 9 to 11.1. I know a CLEAR(Group) does not work. Same problem with a QUEUE and CLASS using BSTRING. When Alexy was posting here he said there was some support for this coming in Clarion 12 but IIRC it was not as complete as the way ANY is handled.

Some workaround ideas.


First try to prevent the RTL initialization (i.e. clear) by adding AUTO to your declaration.

A LIKE(SomeResult)  ,AUTO   !<-- add Auto

A BSTRING is just a LONG that is an Address that points to the BStr structure that contains 2 LONG’s with the Address of the real Unicode String and the Capacity.

So maybe you can change BSTRING to LONG. Then when you need to use it as a BSTRING define a BSTRING OVER(TheLong). Or pass the LONG to a Procedure prototyped as (BSTRING) IIRC the compiler will allow this.

SomeResult_BSTR GROUP,TYPE
State       BSTRING
ActionUrl   BSTRING
Value       BSTRING
Error       GROUP
ErrorCode       BSTRING
Description     BSTRING
            END 
END                               
SomeResult_LNG GROUP,TYPE
State       LONG  !Really BStr
ActionUrl   LONG  !Really BStr
Value       LONG  !Really BStr
Error       GROUP
ErrorCode       LONG  !Really BStr
Description     LONG  !Really BStr
            END 
END
A_Longs  LIKE(SomeResult_LNG)
A_BSTR   LIKE(SomeResult_BSTR),OVER(A_Longs)  !in case need to use as BSTRING

One thing to be careful of is you should not CLEAR(A_Longs) because that will just set all the Longs =Zero and “disconnect” from all the BSTRING’s and leak the memory they had allocated. You MUST not CLEAR(A_BSTR) because Clarion does not handle BSTRING in Group. You would need to each CLEAR(A_BSTR.State) and all the others.


In LibSrc is SVCom.Inc / .Clw with a BString class named CBStr that you may be able to make use of. You would probably still define your Group with all LONGs. I think this class way originally by Andy Ireland for COM support.


In recap a BSTRING is just a LONG, so only when you want to use it as a BSTRING change its type with an OVER or procedure call to prototype (BSTRING).