www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*--------------------------------------------------------------------+
|                                                                     |
|           Copyright (c) 1995, SAS Institute Inc.                    |
|             Unpublished - All Rights Reserved                       |
|                                                                     |
|                     S A S / C  S A M P L E                          |
|                                                                     |
|       Name: LOADMAC                                                 |
|                                                                     |
|   Language: C                                                       |
|                                                                     |
| EntryPoint: MAIN                                                    |
|                                                                     |
| Entry Type: Standard C Entry Linkage  (via main)                    |
|                                                                     |
| Files Note: 'prefix' is the installation defined high level         |
|             qualifier for the SAS/C product.                        |
|                                                                     |
|   Function: Dynamically load and call an assembler routine to       |
|             sum a list of variables and return the sum to the       |
|             caller.                                                 |
|                                                                     |
|    Purpose: Demonstrate SAS/C assembler communications by           |
|             - dynamic loading of assembler programs via loadm       |
|             - using the __ref to build a call-by-reference          |
|               parameter list                                        |
|             - converting remote function pointers to local          |
|               function pointers                                     |
|                                                                     |
| MVS -                                                               |
|     Source: prefix.SAMPLE.ASM(LOADMAC)                              |
|                                                                     |
|    Compile/Link/Go: prefix.SAMPLE.AUX(LOADMAJ)                      |
|                                                                     |
| CMS -                                                               |
|                                                                     |
|     Source: SAMPLASM MACLIB (LOADMAC)                               |
|                                                                     |
|   Assemble: global maclib lcuser                                    |
|             hlasm loadmaa                                           |
|                                                                     |
|       Load: lked loadmaa (libe dynamc name loadmaa                  |
|                                                                     |
|    Compile: global maclib lc370                                     |
|             lc370 loadmac                                           |
|                                                                     |
|       Load: global txtlib lc370std lc370bas                         |
|             load loadmac(nomap rmode 24 amode 24                    |
|                                                                     |
|     Genmod: genmod loadmac                                          |
|                                                                     |
|    Execute: loadmac                                                 |
|                                                                     |
| Notes:                                                              |
|       - LOADMAC sets runtime options in the source.                 |
|                                                                     |
+--------------------------------------------------------------------*/
#include <stdio.h>
#include <dynam.h>
#include <options.h>
#define MODNAME "LOADMAA"

/* The following demonstrates how to specify runtime options in     */
/* in source code.  They are not required for the proper executiuon */
/* of the LOADMA sample.                                            */
extern int _options = _VERSION + _BTRACE + _USAGE + _WARNING;

int main()
{
/*--------------------------------------------------------*/
/* Function pointer for the address returned by loadm.    */
/* Note: by default this is a remote function pointer.    */
/*--------------------------------------------------------*/
  int (*fp) ();            /* C Function Pointer          */

/*--------------------------------------------------------*/
/* Function pointer for the assembler program that will   */
/* be dynamically loaded.  This is a 'local' pointer to   */
/* a program to be called with standard VL-type plist     */
/* that is call-by-REFerence.                             */
/*                                                        */
/* Use of the __ref keyword tells the compiler to build   */
/* a plist with pointers to the formal arguments.         */
/*                                                        */
/*--------------------------------------------------------*/
__local __ref int (*asmfp)();

/*--------------------------------------------------------*/
/* Variables                                              */
/*--------------------------------------------------------*/
int  retcode = 0;
int  h = 1;
int  i = 2;
int  j = 3;
int  k = 4;
int  sum = 0;
int  check_sum;

/*--------------------------------------------------------*/
/*  Load the assembler program dynamically via loadm,     */
/*  loadm returns a remote C function pointer.  If        */
/*  the load fails for any reason, a NULL pointer is      */
/*  returned.                                             */
/*                                                        */
/*  Note: Under MVS the modules to be loaded must reside  */
/*        in STEPLIB, task library, or the system link    */
/*        list.  Under CMS, modules to be loaded may      */
/*        reside in DYNAMC LOADLIB or in other locations  */
/*        defined by use of the addsrch routine of SAS/C. */
/*--------------------------------------------------------*/
loadm(MODNAME, &fp);

if (fp == NULL)              /* Was loadm successful ?    */
   {
    printf("\n\n loadm failed for module %s!!", MODNAME);
    exit(16);
   };

/*--------------------------------------------------------*/
/* The function pointer returned by loadm is a remote     */
/* function pointer which can only be used with calls     */
/* to other C modules.  LOADMAA is an assembler module,   */
/* this requires the remote function pointer be converted */
/* to a local function pointer for the call to LOADMAA.   */
/* An assignment with casting converts the remote         */
/* function pointer to a local function pointer.          */
/*--------------------------------------------------------*/
asmfp = (__ref int (*)()) fp; /* Convert remote(to local  */

/*--------------------------------------------------------*/
/*  Call the assembler routine via the local funciton     */
/*  pointer with 2 arugments.                             */
/*--------------------------------------------------------*/
sum  = (asmfp)(h,i);          /* Summary number 1         */

printf("\n\nVariable Length with 2 arguments, "
       "the sum of %d and %d is %d\n", h, i, sum);

check_sum = h+i;

/*--------------------------------------------------------*/
/* See how things went and set return code accordingly.   */
/*--------------------------------------------------------*/
if (sum == check_sum)  /* Verify Sum is corrrect.*/
  {
   printf("\nSum of %d was correct.\n", sum);
   retcode = 0;
  }
 else
  {
   printf("\nSum of %d was NOT CORRECT!.\n", sum);
   printf("It should have been %d!\n",check_sum);
   retcode = 12;
  };

/*--------------------------------------------------------*/
/*  Call the assembler routine via the local funciton     */
/*  pointer with 4 arugments.                             */
/*--------------------------------------------------------*/
sum  = (asmfp)(h,i,j,k);      /* Summary number 2         */

printf("\n\nVariable Length with 4 arguments, "
       "the sum of %i, %i, %i and %i is %i\n",
        h, i, j, k, sum);

check_sum = h+i+j+k;

/*--------------------------------------------------------*/
/* See how things went and set return code accordingly    */
/* if there is an error.                                  */
/*--------------------------------------------------------*/
if (sum == check_sum)  /* Verify Sum is corrrect.*/
  {printf("\nSum of %d was correct.\n", sum);}
 else
  {
   printf("\nSum of %d was NOT CORRECT!.\n", sum);
   printf("It should have been %d!\n",check_sum);
   retcode = 12;
  };

/*--------------------------------------------------------*/
/*  Unload the assembler function using the remote        */
/*  C function pointer.                                   */
/*--------------------------------------------------------*/
unloadm(fp);
exit(retcode);
}

Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement