byte array to memptr

Posted by OctavioOlguin on 01-Jul-2017 10:46

I had this procedure:

PROCEDURE ByteArrayToMemptr :

    DEFINE INPUT  PARAMETER poBytes  AS "System.Byte[]":U NO-UNDO.
    DEFINE OUTPUT PARAMETER myMemptr AS MEMPTR NO-UNDO.


    DEFINE VARIABLE oIntPointer AS System.IntPtr NO-UNDO .
    MESSAGE 1 " : " poBytes:Length .
    SET-SIZE (myMemptr) = poBytes:Length .
    MESSAGE 2.
    oIntPointer = NEW System.IntPtr (GET-POINTER-VALUE (myMemptr)).
    MESSAGE 3.
    System.Runtime.InteropServices.Marshal:Copy (poBytes, 0, oIntPointer, poBytes:Length).
    MESSAGE 4.
    DELETE OBJECT oIntPointer.

END PROCEDURE.

But since upgraded to 11.7, it won't work.

The message were inserted to debug.

when run, poBytes:Length is 512, and message 3 & 4 never get shown.

The error is "System.OverflowException: value too big or to little for Int32

Posted by Stefan Drissen on 01-Jul-2017 15:07

We ran into something similar - get-pointer-value is returning a lot more 64 bit values in 11.7 than in 11.6 where they all seemed to be 32 bit. According to support "The same issue could potentially have been encountered in 11.6.3 but it is much more likely to happen in 11.7 on Windows 8.1 and Windows 10 because of a) a change to how we compile OpenEdge executables and b) a change in newer versions of Windows"

In your case however it seems that the wrong signature is being determined for System.IntPtr - maybe you can work-around it by using an intermediate int64 to store your get-pointer-value.

All Replies

Posted by Stefan Drissen on 01-Jul-2017 15:07

We ran into something similar - get-pointer-value is returning a lot more 64 bit values in 11.7 than in 11.6 where they all seemed to be 32 bit. According to support "The same issue could potentially have been encountered in 11.6.3 but it is much more likely to happen in 11.7 on Windows 8.1 and Windows 10 because of a) a change to how we compile OpenEdge executables and b) a change in newer versions of Windows"

In your case however it seems that the wrong signature is being determined for System.IntPtr - maybe you can work-around it by using an intermediate int64 to store your get-pointer-value.

Posted by OctavioOlguin on 01-Jul-2017 17:00

Thanks Stefan!!!

That was it!!!

Posted by OctavioOlguin on 01-Jul-2017 17:02

Thanks Stefan!!

That was it!!!

Posted by goo on 03-Feb-2020 13:48

Hi, could you share the answare ? :-)

Posted by Mike Fechner on 03-Feb-2020 13:58

This works for me:

/**
     * Purpose: Converts a .NET Byte[] to an ABL MEMPTR
     * Notes:
     * @param poBytes The System.Byte[] to convert to a MEMPTR
     * @return The new MEMPTR with the data from the Byte[]
     */
    METHOD PUBLIC STATIC MEMPTR ByteArrayToMemptr (poBytes AS "System.Byte[]":U):

        DEFINE VARIABLE mptr        AS MEMPTR        NO-UNDO .
        DEFINE VARIABLE oIntPointer AS System.IntPtr NO-UNDO .
        DEFINE VARIABLE iPtr64      AS INT64         NO-UNDO .
        DEFINE VARIABLE iPtr32      AS INTEGER       NO-UNDO .

        SET-SIZE (mptr) = poBytes:Length .

        IF SessionHelper:ProcessBitness() = 32 THEN DO:
            iPtr32 = GET-POINTER-VALUE (mptr) .

            oIntPointer = NEW System.IntPtr (iPtr32).
        END .
        ELSE DO:
            iPtr64 = GET-POINTER-VALUE (mptr) .

            oIntPointer = NEW System.IntPtr (iPtr64).
        END.

        System.Runtime.InteropServices.Marshal:Copy (poBytes, 0, oIntPointer, poBytes:Length).

        RETURN mptr .

        FINALLY:
            IF VALID-OBJECT (oIntPointer) THEN
                DELETE OBJECT oIntPointer.
        END FINALLY.

    END METHOD .

And then

    /*------------------------------------------------------------------------------
        Purpose: Returns the "bitness" of the current process (32 / 64 bit)
        Notes:
        @return 32 or 64 depending on the current Process process
    ------------------------------------------------------------------------------*/
    METHOD PUBLIC STATIC INTEGER ProcessBitness ():

        &IF DEFINED (DotNetAccessible) NE 0 &THEN

        &IF PROVERSION BEGINS "10" &THEN
        RETURN 32 . /* no 64 bit Progress on Windows on OE10 */
        &ELSE
        IF System.Environment:Is64BitProcess THEN
            RETURN 64.
        ELSE
            RETURN 32.
        &ENDIF

        &ELSE
        RETURN 64. /* no 32 bit Progress on Linux anymore */
        &ENDIF

    END METHOD .

Posted by Stefan Drissen on 03-Feb-2020 14:05

If on a not too old version, you can use the built in PROCESS-ARCHITECTURE function to get the bitness.

Posted by goo on 03-Feb-2020 14:16

Big Thanx Mike !!
 
//Geir Otto
 

Posted by Peter Judge on 03-Feb-2020 15:06

... "not too old" being 11.3.0+

Posted by goo on 03-Feb-2020 17:18

I got a good one from Mike, so everything is swell...

Sendt fra min iPad

3. feb. 2020 kl. 16:04 skrev Stefan Drissen <bounce-14941@community.progress.com>:


<ProgressEmailLogo-png_2D00_150x42x2-png>
Update from Progress Community
<4TWXR5OO3TXP-jpg_2D00_70x70x2-jpg>
Stefan Drissen

If on a not too old version, you can use the built in PROCESS-ARCHITECTURE function to get the bitness.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

Posted by goo on 17-Feb-2020 12:46

The MemptrToByteArray fails for me….
 
I loaded a json file into a memptr, and it gives me and error when it comes to nPtr, never coming to ‘here..2’
 
Can you see why?
 
//Geir Otto
 
 
 
 

Posted by Mike Fechner on 17-Feb-2020 12:50

Maybe I’m old fashioned. But I do care about error messages &#128522;
 
Von: goo <bounce-goo@community.progress.com>
Gesendet: Montag, 17. Februar 2020 13:48
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] byte array to memptr
 
Update from Progress Community
 
The MemptrToByteArray fails for me….
 
I loaded a json file into a memptr, and it gives me and error when it comes to nPtr, never coming to ‘here..2’
 
Can you see why?
 
//Geir Otto
 
 
 
 

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Stefan Drissen on 17-Feb-2020 13:02

You need to use an intermediate int64 variable to pick up the correct signature.

Posted by goo on 17-Feb-2020 13:06

&#128522; sorry… but after looking at the code, I saw suddenly that it did not check for ProcessBitness…
 
Fix…
 
  METHOD PUBLIC STATIC "System.Byte[]" MemptrToByteArray( pmptr AS MEMPTR ):
    DEFINE VARIABLE oIntPointer AS System.IntPtr NO-UNDO .
    DEFINE VARIABLE iPtr64      AS INT64         NO-UNDO .
    DEFINE VARIABLE vInt        AS INT         NO-UNDO .
    DEFINE VARIABLE iPtr32      AS INTEGER       NO-UNDO .
    DEFINE VARIABLE nBytes AS "System.Byte[]".
 
    vInt = GET-SIZE(pmPtr).
   
    nBytes = NEW "System.Byte[]"(vInt).
 
    IF oo.DataHelper.SessionHelper:ProcessBitness() = 32 THEN DO:
        iPtr32 = GET-POINTER-VALUE (pmptr) .
 
        oIntPointer = NEW System.IntPtr (iPtr32).
    END .
    ELSE DO:
        iPtr64 = GET-POINTER-VALUE (pmptr) .
 
        oIntPointer = NEW System.IntPtr (iPtr64).
    END.
 
    System.Runtime.InteropServices.Marshal:Copy(oIntPointer, nBytes, 0, vInt).
    RETURN nBytes.
    FINALLY:
      /* nPtr = ?.*/
      DELETE OBJECT oIntPointer.
      SET-SIZE(pmPtr) = 0.
      nBytes = ?.
    END.
  
  END METHOD.
 
 

This thread is closed