Try OpenEdge Now
skip to main content
Programming Interfaces
External Program Interfaces : Shared Library and DLL Support : Passing parameters to a shared library routine : Passing arrays as parameters : MEMPTR arrays
 
MEMPTR arrays
If the DLL requires an array of pointers, where each pointer either points at a string or a structure, you can pass an ABL MEMPTR array. For INPUT or INPUT-OUTPUT parameters, you initialize each MEMPTR as appropriate to contain the string or structure to pass for INPUT. If it is an INPUT-OUTPUT parameter, you must insure that the allocated size (that is, the size set by SET-SIZE) is large enough to hold any expected output value, not just large enough to hold the input value. For an OUTPUT parameter, if the DLL expects an array of pointers to allocated buffers, you must use SET-SIZE to the required size for each MEMPTR in the array.
If the DLL allocates memory for a set of strings or structures and returns them as an array of pointers, you must set each MEMPTR to at least the size of a pointer (for example, 4 or 8 bytes depending on the platform). You then use the GET-POINTER-VALUE and SET-POINTER-VALUE functions to access the data on return. (For more information on the GET- and SET-POINTER-VALUE functions, see OpenEdge Development: ABL Reference.) If you want to pass NULL as one or more of the pointers, the corresponding MEMPTR in the array can be a null MEMPTR, meaning that it is either uninitialized or that you did a SET-SIZE on it to set it to zero length. For information on passing a MEMPTR parameter, see UsingMEMPTR variables as parameters.
Here is an example C Code Prototype for a function called getNames:
getNames(char **pnameList);
This example is the equivalent ABL for the getNames procedure when accessing the shared library statically. In this case, the DLL does not allocate the buffer, but expects to be passed an array of buffer pointers:
DEFINE VARIABLE ix     AS INTEGER NO-UNDO.
DEFINE VARIABLE mNames AS MEMPTR  NO-UNDO EXTENT 10.

DO ix = 1 TO EXTENT(mNames):
  SET-SIZE(mNames[ix]) = 50.
END.

RUN getNames (mNames).

DO ix = 1 TO EXTENT(mNames):
  DISPLAY GET-STRING(mNames[ix], 1).
END.

PROCEDURE getNames EXTERNAL "myApp.dll" PERSISTENT:
  DEFINE OUTPUT PARAMETER names AS MEMPTR NO-UNDO.
END.
This example is the equivalent ABL for the getNames procedure when accessing the shared library dynamically:
DEFINE VARIABLE hCall  AS HANDLE  NO-UNDO.
DEFINE VARIABLE ix     AS INTEGER NO-UNDO.
DEFINE VARIABLE mNames AS MEMPTR  NO-UNDO EXTENT 10.

DO ix = 1 TO EXTENT(mNames):
  SET-SIZE(mNames[ix]) = 50.
END.

CREATE CALL hCall.
ASSIGN
  hCall:CALL-NAME             = "getNames"
  hCall:LIBRARY               = "myApp.dll"
  hCall:CALL-TYPE             = DLL-CALL-TYPE
  hCall:RETURN-VALUE-DLL-TYPE = "CHARACTER"
  hCall:PERSISTENT            = TRUE
  hCall:NUM-PARAMETERS        = 1.

hCall:SET-PARAMETER(1, "MEMPTR", "INPUT", mNames).
hCall:INVOKE( ).

DO ix = 1 TO EXTENT(mNames):
  DISPLAY GET-STRING(mNames[ix], 1).
END.