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?
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)
.