Page 1 of 1
PRIM_KCOL - Invalid_Cast error
Posted: Thu Jul 06, 2023 8:29 pm
by cesarrafael
Hi All,
This might be a very basic thing, however I was wondering if someone could give me a reason why I get a * *INVALID_CAST error when using this situation:
==CR_FUN1 (Function)
Function Options(*DIRECT)
*
Define Field(#W_text) Type(*CHAR) Length(60)
*MyField is a Alpha 60
*
Define_Com Class(#CR_TST2) Name(#getCollection) Scope(*APPLICATION)
Define_Com Class(#PRIM_KCOL<#STD_STRG #MyField>) Name(#KeyedCollection1) Reference(*DYNAMIC)
#KeyedCollection1 <= #getCollection.Mycoll()
For Each(#Item) In(#KeyedCollection1)
#W_text := #Item.Value
Endfor
Return
== CR_TST2 (reusable part)
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT) Options(*FINAL)
*
Mthroutine Name(MyColl) Help('Test Invalid Cast') Options(*FINAL)
Define_Map For(*RESULT) Class(#prim_kcol<#STD_STRG #MyField>) Name(#PassCollection) Pass(*BY_REFERENCE)
If_Ref Com(#PassCollection) Is(*NULL)
Set_Ref Com(#PassCollection) To(*CREATE_As #prim_kcol<#STD_STRG #MyField>)
Endif
#PassCollection.RemoveAll
#MyField := 'test1'
#PassCollection<#MyField> := 'Cesartest'
*
Endroutine
*
End_Com
== Error message
Message : Unexpected or unhandled runtime error - Failure( *INVALID_CAST ) ReportedBy( File:X_VarEvaluations Line:24272 )
I've tried several things and always get this error....am I doing something wrong?
Many thanks!
Re: PRIM_KCOL - Invalid_Cast error
Posted: Sat Jul 08, 2023 12:08 am
by dominique
Hi Rafael
As far as I know you can't create instance of a result collection. Hope that will help

- Bild000080.jpg (78.88 KiB) Viewed 19801 times
Code: Select all
Evtroutine Handling(#COM_OWNER.CreateInstance)
#com_self.MyCollIn( #com_self.MyCollGet )
Endroutine
Mthroutine Name(MyCollGet)
Define_Map For(*RESULT) Class(#PRIM_KCOL<#STD_TEXT #STD_NUM>) Name(#Collection) Pass(*BY_REFERENCE)
Define_Com Class(#PRIM_KCOL<#STD_TEXT #STD_NUM>) Name(#KeyedCollectionOut)
#KeyedCollectionOut<1> <= *New #STD_TEXT
#KeyedCollectionOut<1> := "Value 1"
#KeyedCollectionOut<2> <= *New #STD_TEXT
#KeyedCollectionOut<2> := "Value 2"
#Collection <= #KeyedCollectionOut
Endroutine
Mthroutine Name(MyCollIn)
Define_Map For(*INPUT) Class(#PRIM_KCOL<#STD_TEXT #STD_NUM>) Name(#Collection) Pass(*BY_REFERENCE)
Define_Com Class(#PRIM_KCOL<#STD_TEXT #STD_NUM>) Name(#KeyedCollectionIn) Reference(*DYNAMIC)
#KeyedCollectionIn <= #Collection
For Each(#item) In(#KeyedCollectionIn)
Use Builtin(MESSAGE_BOX_ADD) With_Args(#item)
Endfor
Use Builtin(MESSAGE_BOX_Show)
Endroutine
Re: PRIM_KCOL - Invalid_Cast error
Posted: Mon Jul 10, 2023 9:09 pm
by cesarrafael
Hi Dominique,
Many thanks!
Yes, it works if both methodroutine are in the same function/reusable part. However if "MyCollIn" and "MyCollGet" are in separate objects, it crashes with the Invalid_cast error....Any idea why this happens?
Cheers,
Re: PRIM_KCOL - Invalid_Cast error
Posted: Tue Jul 11, 2023 12:08 pm
by BrendanB
Cesar,
not sure if you intentionally misspelt the #STD_STRG instead of #STD_STRNG...
But, why pass the reference at all? you could just make the collection a property of the object.
Call the method, then use the property.
Code: Select all
==CR_FUN1 (Function)
Function Options(*DIRECT)
*
Define Field(#W_text) Type(*CHAR) Length(60)
*MyField is a Alpha 60
*
Define_Com Class(#CR_TST2) Name(#getCollection) Scope(*APPLICATION)
* call method to populate the property
#getCollection.MyColl()
* use the property directly...
For Each(#Item) In(#getCollection.PassCollection)
#W_text := #Item.Value
Endfor
Return
== CR_TST2 (reusable part)
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT) Options(*FINAL)
*
define_com class(#prim_kcol<#STD_STRNG #MyField>) name(#PassCollection)
define_pty name(PassCollection) get(*REFERENCE #PassCollection)
*
Mthroutine Name(MyColl) Help('Test Invalid Cast') Options(*FINAL)
#PassCollection.RemoveAll
#MyField := 'test1'
#PassCollection<#MyField> := 'Cesartest'
*
Endroutine
*
End_Com
Re: PRIM_KCOL - Invalid_Cast error
Posted: Tue Jul 11, 2023 12:24 pm
by BrendanB
You could even take it 1 step further:
Code: Select all
Function Options(*DIRECT)
Begin_Com Role(*EXTENDS #PRIM_OBJT) Options(*FINAL)
*
Define_Com Class(#prim_kcol<#STD_STRNG #std_desc>) Name(#PassCollection)
Define_Pty Name(PassCollection) Get(*REFERENCE #PassCollection)
Define_Pty Name(KeyedColl) Get(pGetPassCollection)
*
Ptyroutine Name(pGetPassCollection)
Define_Map For(*OUTPUT) Class(#prim_kcol<#STD_STRNG #std_desc>) Name(#Property) Pass(*BY_REFERENCE)
#COM_SELF.MyColl
#Property <= #PassCollection
Endroutine
Mthroutine Name(MyColl) Help('Test Invalid Cast') Options(*FINAL)
* Define_Map For(*RESULT) Class(#prim_kcol<#STD_STRNG #std_desc>) Name(#PassCollection) Pass(*BY_REFERENCE)
* #PassCollection <= (*New #PRIM_KCOL<#STD_STRNG #STD_DESC>)
#PassCollection.RemoveAll
#STD_DESC := 'test1'
#PassCollection<#STD_DESC> := 'Cesartest'
*
Endroutine
*
End_Com
CR_FUN1=======
Function Options(*DIRECT)
*
Define Field(#W_text) Type(*CHAR) Length(60)
* MyField is a Alpha 60
*
Define_Com Class(#CR_TST2) Name(#getCollection) Scope(*APPLICATION)
For Each(#Item) In(#getCollection.KeyedColl)
#W_text := #Item.Value
Endfor
Return
Re: PRIM_KCOL - Invalid_Cast error
Posted: Tue Jul 11, 2023 6:52 pm
by cesarrafael
Hi Brendan,
Many thanks! I actually need to store de keyed collection on my calling function, i.e. I need to call a routine on another program and store it on my calling (initial) program...
But no matter what I do, when I try to pass the keyed collection between routines in differerent objects, I get an *Invalid_cast error!
Cheers,
Re: PRIM_KCOL - Invalid_Cast error
Posted: Sat Jul 15, 2023 2:38 am
by jonno
I am also having the same issue although a slightly different scenario namely:
server module method prim_kcol <= RP method prim_kcol
Note: we have it working on the web e.g, web page method <= RP method and also array collections work fine
I tried the suggestion of using a property routine but after a quick try that failed with the same error "invalid_cast", will look again in more detail.
LANSA support response was "the explanation is that this was an unavoidable restriction related to the way that LANSA generates the C++ Code.
The solution is to wrap the keyed collection into a reusable part, and then pass that around instead."