I'm writing some code that'll pass memptrs around, and I need to confirm that MEMPTR are pass-by-reference and not pass-by-value.
In other words - for this code snippet:
RUN Memptr/Callee.p(mptrTest).
Will the parameter in Callee.p reference the memory pointed to by mptrTest, or a copy of that area?
I know that
Assign Mptr1 = Mptr2.
Creates a new memptr and copies the values from 2 to 1 - I want to make sure that passing a memptr reference to a method, procedure, or function does not do this.
Yes, the parameter is by reference - different from the assignment, which makes a copy. Try this code:
DEFINE VAR mm AS MEMPTR.
SET-SIZE(mm) = 10.
PUT-STRING(mm, 1) = "ABC".
RUN foo(mm).
MESSAGE "In caller" SKIP
GET-STRING(mm, 1) SKIP
GET-POINTER-VALUE(mm)
VIEW-AS ALERT-BOX.
PROCEDURE foo:
DEFINE INPUT PARAMETER mm2 AS MEMPTR.
PUT-STRING(mm2, 4) = "XXX".
MESSAGE "Inside foo" SKIP
GET-STRING(mm2, 1) SKIP
GET-POINTER-VALUE(mm)
VIEW-AS ALERT-BOX.
END.
mmmm. memory pointers. My favourite feature in a 4GL ;)
Yes, the parameter is by reference - different from the assignment, which makes a copy. Try this code:
DEFINE VAR mm AS MEMPTR.
SET-SIZE(mm) = 10.
PUT-STRING(mm, 1) = "ABC".
RUN foo(mm).
MESSAGE "In caller" SKIP
GET-STRING(mm, 1) SKIP
GET-POINTER-VALUE(mm)
VIEW-AS ALERT-BOX.
PROCEDURE foo:
DEFINE INPUT PARAMETER mm2 AS MEMPTR.
PUT-STRING(mm2, 4) = "XXX".
MESSAGE "Inside foo" SKIP
GET-STRING(mm2, 1) SKIP
GET-POINTER-VALUE(mm)
VIEW-AS ALERT-BOX.
END.
Thx Laura - I did something similar with a caller / callee procedure and the get-point-value() was the same on both sides of the call.
Being the paranoid developer I am, I wanted to make sure what I thought I was seeing was, in fact, correct, and wouldn't result in a memory leak, or information not being passed back to the caller.
> On Jul 6, 2017, at 2:45 PM, jmls wrote:
>
> mmmm. memory pointers. My favourite feature in a 4GL ;)
>
>
>
indeed. but we had to add it to support various interfaces to the outside world.
Tim,
One thing that becomes important when working with MEMPTRs is that they can only have a size allocated once in the ABL. You cannot resize them dynamically (although hopefully this will be mitigated/solved soon). This is especially pertinent when working with sockets - you cannot be sure how many chunks of data you are receiving and how much data is in each chunk. Now you get into a game of copying data and and/or reallocating memory and general pain ensues.
I ran into this when writing the HTTP Client and ended up creating a wrapper about all that painful, annoying stuff. It's called a ByteBucket: documentation.progress.com/.../OpenEdge.Core.ByteBucket.html . You can just throw data into/at it and it'll do the internal resizing and allocations for you.