home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* SAMPLE PROGRAM 04: MAIN04.C */
- /* */
- /* COPYRIGHT: */
- /* ---------- */
- /* Copyright (C) International Business Machines Corp., 1991,1992. */
- /* */
- /* DISCLAIMER OF WARRANTIES: */
- /* ------------------------- */
- /* The following [enclosed] code is sample code created by IBM */
- /* Corporation. This sample code is not part of any standard IBM product */
- /* and is provided to you solely for the purpose of assisting you in the */
- /* development of your applications. The code is provided "AS IS", */
- /* without warranty of any kind. IBM shall not be liable for any damages */
- /* arising out of your use of the sample code, even if they have been */
- /* advised of the possibility of such damages. */
- /* */
- /******************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #define INCL_DOS
- #include <os2.h>
-
- #include "sample04.h"
-
- static char * _Seg16 foo2;
- static char *foo3;
- static char *foo4;
- static char *(* _Far16 plugh4)( void );
-
- static void _Far16 _Pascal xyzzy( void );
-
- int main( void ) {
- HMODULE handle;
- APIRET rc;
- CHAR objbuffer[261];
-
- /*
- * Call a 16-bit routine directly. plugh1() sets the variable foo1 to point
- * to the first string.
- */
-
- plugh1();
- puts( foo1 );
-
- /*
- * Call a 16-bit routine to set a string indirectly. Notice that foo2 has
- * been declared as a _Seg16 pointer. This allows it to be used directly
- * by plugh2(). Only the first level of indirection of the pointer (in this
- * case, the address calculation) is done automatically by the compiler.
- * The second level of indirection (in this case, the pointer being passed)
- * must be given an explicit _Seg16 qualifer.
- */
-
- plugh2( &foo2 );
- puts( foo2 );
-
- /*
- * Call a 16-bit routine which in turn calls a 32-bit routine. xyzzy() is
- * a 16-bit routine defined in a 32-bit program. We call plugh3(), passing
- * the address of xyzzy() as a parameter. plugh3() then calls back to the
- * 32-bit routine xyzzy(), which prints a string.
- */
-
- plugh3( xyzzy );
-
- /*
- * Call a function whose address is calculated at run-time. plugh4 is a
- * pointer to a 16-bit function found in the DLL named samp04b.dll. We
- * call DosQueryProcAddr() to get the address of the function. Notice that
- * the name of the function which we ask for is "_plugh4". The underscore
- * is there because that is the name by which the 16-bit routine is known
- * (this is a relic from the 16-bit compiler's variable naming scheme.)
- *
- * Notice also that we cast the address of the variable plugh4 to the
- * type (PFN *). This tricks the compiler into thinking that the linkage
- * type of the function pointer matches the linkage type asked for in the
- * prototype for DosLoadModule(). This is a potentially dangerous trick.
- * Be sure that the linkage type of the function pointer which you pass to
- * DosLoadModule() is the same as the linkage of the function whose address
- * you are retrieving. If it isn't, you will be setting yourself up for a
- * potentially long and frustrating debugging session. Be sure that you
- * know what you are doing.
- */
-
- if ( rc = DosLoadModule( objbuffer, 261, ".\\samp04b.dll", &handle ) ) {
- printf( "Error loading DLL. rc = %ul, guilty party = %s\n", rc, objbuffer );
- return -1;
- }
-
- if ( rc = DosQueryProcAddr( handle, 0, "_plugh4", (PFN *)&plugh4 ) )
- printf ( "Error loading routine. rc = %ul\n", rc );
- else {
- foo4 = plugh4();
- puts( foo4 );
- }
-
- if ( rc = DosFreeModule( handle ) ) {
- printf( "Error freeing DLL. rc = %ul\n", rc );
- return -1;
- }
-
- return 0;
- }
-
- /*
- * Define a 32-bit routine with a 16-bit entry sequence. This function can
- * be called indirectly (through a function pointer) from a 16-bit routine.
- * If there were any parameters, they would be moved around on the stack so
- * that they would be usable from a 32-bit routine. Once the function
- * prolog has executed, the chip is switched into 32-bit mode and the function
- * body is executed. The chip switches back to 16-bit mode on the fucntion
- * return.
- */
-
- static void _Far16 _Pascal xyzzy( void ) {
- puts( "And was the holy lamb of God" );
- return;
- }
-