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 >
Wrap
C/C++ Source or Header
|
1995-06-29
|
5KB
|
124 lines
/******************************************************************************/
/* SAMPLE PROGRAM 04: SAMPLE04.C */
/* */
/* 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>
#pragma info(nocnd)
#include "sample04.h"
#pragma import(foo1,,"SAMP04A",0)
#pragma import(plugh1,,"SAMP04A",0)
#pragma import(plugh2,,"SAMP04A",0)
#pragma import(plugh3,,"SAMP04A",0)
static char * _Seg16 foo2;
static char *foo3;
static char *foo4;
static char *(* _Far16 _Cdecl 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;
}