home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / SAMPLES / COMPILER / SAMPLE04 / SAMPLE04.C < prev    next >
Text File  |  1993-03-15  |  5KB  |  122 lines

  1. /******************************************************************************/
  2. /* SAMPLE PROGRAM 04: SAMPLE04.C                                              */
  3. /*                                                                            */
  4. /* COPYRIGHT:                                                                 */
  5. /* ----------                                                                 */
  6. /* Copyright (C) International Business Machines Corp., 1991,1993.            */
  7. /*                                                                            */
  8. /* DISCLAIMER OF WARRANTIES:                                                  */
  9. /* -------------------------                                                  */
  10. /* The following [enclosed] code is sample code created by IBM                */
  11. /* Corporation.  This sample code is not part of any standard IBM product     */
  12. /* and is provided to you solely for the purpose of assisting you in the      */
  13. /* development of your applications.  The code is provided "AS IS",           */
  14. /* without warranty of any kind.  IBM shall not be liable for any damages     */
  15. /* arising out of your use of the sample code, even if they have been         */
  16. /* advised of the possibility of such damages.                                */
  17. /*                                                                            */
  18. /******************************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #define INCL_DOS
  23. #include <os2.h>
  24.  
  25. #include "sample04.h"
  26.  
  27. static char        * _Seg16 foo2;
  28. static char        *foo3;
  29. static char        *foo4;
  30. static char        *(* _Far16 plugh4)( void );
  31.  
  32. static void         _Far16 _Pascal xyzzy( void );
  33.  
  34. int main( void ) {
  35.   HMODULE           handle;
  36.   APIRET            rc;
  37.   CHAR              objbuffer[261];
  38.  
  39.   /*
  40.    * Call a 16-bit routine directly.  plugh1() sets the variable foo1 to point
  41.    * to the first string.
  42.    */
  43.  
  44.   plugh1();
  45.   puts( foo1 );
  46.  
  47.   /*
  48.    * Call a 16-bit routine to set a string indirectly.  Notice that foo2 has
  49.    * been declared as a _Seg16 pointer.  This allows it to be used directly
  50.    * by plugh2().  Only the first level of indirection of the pointer (in this
  51.    * case, the address calculation) is done automatically by the compiler.
  52.    * The second level of indirection (in this case, the pointer being passed)
  53.    * must be given an explicit _Seg16 qualifer.
  54.    */
  55.  
  56.   plugh2( &foo2 );
  57.   puts( foo2 );
  58.  
  59.   /*
  60.    * Call a 16-bit routine which in turn calls a 32-bit routine.  xyzzy() is
  61.    * a 16-bit routine defined in a 32-bit program.  We call plugh3(), passing
  62.    * the address of xyzzy() as a parameter.  plugh3() then calls back to the
  63.    * 32-bit routine xyzzy(), which prints a string.
  64.    */
  65.  
  66.   plugh3( xyzzy );
  67.  
  68.   /*
  69.    * Call a function whose address is calculated at run-time.  plugh4 is a
  70.    * pointer to a 16-bit function found in the DLL named samp04b.dll.  We
  71.    * call DosQueryProcAddr() to get the address of the function.  Notice that
  72.    * the name of the function which we ask for is "_plugh4".  The underscore
  73.    * is there because that is the name by which the 16-bit routine is known
  74.    * (this is a relic from the 16-bit compiler's variable naming scheme.)
  75.    *
  76.    * Notice also that we cast the address of the variable plugh4 to the
  77.    * type (PFN *).  This tricks the compiler into thinking that the linkage
  78.    * type of the function pointer matches the linkage type asked for in the
  79.    * prototype for DosLoadModule().  This is a potentially dangerous trick.
  80.    * Be sure that the linkage type of the function pointer which you pass to
  81.    * DosLoadModule() is the same as the linkage of the function whose address
  82.    * you are retrieving.  If it isn't, you will be setting yourself up for a
  83.    * potentially long and frustrating debugging session.  Be sure that you
  84.    * know what you are doing.
  85.    */
  86.  
  87.   if ( rc = DosLoadModule( objbuffer, 261, ".\\samp04b.dll", &handle ) ) {
  88.     printf( "Error loading DLL.  rc = %ul, guilty party = %s\n", rc, objbuffer );
  89.     return -1;
  90.   }
  91.  
  92.   if ( rc = DosQueryProcAddr( handle, 0, "_plugh4", (PFN *)&plugh4 ) )
  93.     printf ( "Error loading routine.  rc = %ul\n", rc );
  94.   else {
  95.     foo4 = plugh4();
  96.     puts( foo4 );
  97.   }
  98.  
  99.   if ( rc = DosFreeModule( handle ) ) {
  100.     printf( "Error freeing DLL.  rc = %ul\n", rc );
  101.     return -1;
  102.   }
  103.  
  104.   return 0;
  105. }
  106.  
  107. /*
  108.  * Define a 32-bit routine with a 16-bit entry sequence.  This function can
  109.  * be called indirectly (through a function pointer) from a 16-bit routine.
  110.  * If there were any parameters, they would be moved around on the stack so
  111.  * that they would be usable from a 32-bit routine.  Once the function
  112.  * prolog has executed, the chip is switched into 32-bit mode and the function
  113.  * body is executed.  The chip switches back to 16-bit mode on the fucntion
  114.  * return.
  115.  */
  116.  
  117. static void _Far16 _Pascal xyzzy( void ) {
  118.   puts( "And was the holy lamb of God" );
  119.   return;
  120. }
  121.  
  122.