fetchep() — Share writable static

Standards

Standards / Extensions C or C++ Dependencies
Language Environment C only  

Format

#include <stdlib.h>

void ( *fetchep( void ( *entry_point)()))();

General description

Dynamically fetches a set of functions with shared writable static variables. fetchep() is used to register an entry point. It returns a pointer that may be passed across the fetch boundary and used as if it were the original entry point. Therefore, you can create more than one entry point from a fetched module. A call to the new entry point will use the same writable static as the original fetch pointer uses on each invocation.

fetchep() is called within a fetched module but not from the same level as the fetch() call. If fetchep() is called in the root program that is not a fetched module, fetchep() returns a fetch pointer that will use the root program's writable static (if any exists).

If the entry_point given as input to fetchep() is a function address external to the current module or is an non-valid function address, use of the resulting pointer returned from the call will result in undefined behavior.

If writable static is required, then this directive must be used:
#pragma linkage(entry_point, FETCHABLE)

In addition, the steps for fetching a reentrant module must be followed as described in fetch() — Get a load module. If writable static is not required, the C module using fetchep() need not contain the directive: #pragma linkage(…, FETCHABLE).

You can release the new fetch pointer without any effect on the original or any other fetch pointer created from the original fetch pointer. If the original fetched function is released, however, all the fetch pointers created using the fetchep() function will also be released. Trying to use a fetch pointer once it has been released or its origin has been released will result in undefined behavior.

To avoid infringing on the user's name space, this nonstandard function has two names. One name, the external entry point name, is prefixed with two underscore characters, and the other name is not. The name without the prefix underscore characters is exposed only when you use LANGLVL(EXTENDED).

Note: The external entry point name for fetchep() is __ftchep(), NOT __fetchep().

To use this function, you must either invoke the function using its external entry point name (that is, the name that begins with two underscore characters __ftchep(), or compile with LANGLVL(EXTENDED). When you use LANGLVL(EXTENDED) any relevant information in the header is also exposed.

Examples

These examples and diagram demonstrate the program flow of a call to fetch() and subsequent calls to fetchep().
/* The module that calls fetch()    */
#include <stdlib.h>
typedef int (*FUNC_T)();

int main(void) {
FUNC_T (*myfunc)();
FUNC_T myfunc1;
FUNC_T myfunc2;
FUNC_T myfunc3;

myfunc = (FUNC_T (*)())fetch("MYMOD");
myfunc1 = myfunc(0);
myfunc2 = myfunc(1);
myfunc3 = myfunc(2);
}
/*
   The following code is the fetched module.
   Please see fetch() for information on how to compile and link the
   above.
 */

/*   inside MYMOD   */
#include <stdlib.h>
typedef int (*FUNC_T)();
int k;              /* global variable to share within MYMOD */
#pragma linkage(x, fetchable)
FUNC_T x(int a)
{
  switch(a)
    {
    case 0:
       return (FUNC_T)fetchep((void(*)())func1);
    case 1:
       return (FUNC_T)fetchep((void(*)())func2);
    case 2:
       return (FUNC_T)fetchep((void(*)())func3);
    }
{

int func1(int a, int b)
{
k = 6;
⋮
}

int func2(int a, int b)
{
k = 4;
⋮
}

int func3(int a, int b)
{
k = 5;
⋮
}
Figure 1. Program Flow of fetchep()
Program flow of fetchep()

Related information