home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / COMPILER / SAMPLE04 / SAMPLE04.C < prev    next >
C/C++ Source or Header  |  1995-06-29  |  5KB  |  124 lines

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