[ Home | Syllabus |Course Notes]

Exported Function (snd.cpp)
// snd.cpp
#include <windows.h>
#include "snd.h"
void MultiHonk(DWORD iterations)
{
UINT i;
for (i=0; i<iterations; i++)
{
Beep(200, 50);
Sleep(1000);
}
}
// Header file for library side
// snd.h
extern "C"
{
void MultiHonk(DWORD iterations); // plain old function prototype
}
; snd.def LIBRARY snd EXPORTS MultiHonk
// Used by "lib" command e.g.
lib -def:snd.def -machine:i386 -out:snd.lib
// honker1.cpp
// No evidence of using a DLL
#include <windows.h>
#include <stdlib.h>
#include <iostream.h>
#include "sndlt.h" // same as snd.h above
VOID main(VOID)
{
DWORD iterations;
CHAR iterStr[100];
cout << "Enter the number of beeps to produce: ";
cin.getline(iterStr, 100);
iterations=atoi(iterStr);
// make the beeps
MultiHonk(iterations);
}
Normally, they are created and stored in known directories.
APP=honker1 NODEBUG=1 !include <ntwin32.mak> $(APP).exe: $(APP).obj $(link) $(conlflags) $(ldebug) \ $(conlibs) snd.lib $(APP).obj \ -out:$(APP).exe $(APP).obj: $(APP).cpp sndlt.h $(cc) $(cflags) $(cdebug) $(cvars) \ $(APP).cpp
The above example was made easier by using Load Time Linking.
RUN TIME LINKING:
E.G. Loading the MAPI.DLL e-mail functions in WORD
// sndrt.h void (*MultiHonk)(DWORD iterations);
// honker2.cpp
#include <windows.h>
#include <stdlib.h>
#include <iostream.h>
#include "sndrt.h"
VOID main(VOID)
{
DWORD iterations;
CHAR iterStr[100];
CHAR modName[MAX_PATH];
HINSTANCE sndHandle;
cout << "Enter the number of beeps to produce: ";
cin.getline(iterStr, 100);
iterations=atoi(iterStr);
// map snd.dll into process
sndHandle=LoadLibraryEx("snd", NULL, 0);
if (sndHandle == NULL)
{
cerr << "Sorry, unable to use DLL." << endl;
return;
}
else
{
// load function name with address mapped from
// snd.dll
MultiHonk=(void (*)(DWORD))GetProcAddress(
sndHandle, "MultiHonk");
if (MultiHonk == NULL)
{
cerr
<< "Sorry, MultiHonk function not in DLL."
<< endl;
// release the DLL
FreeLibrary(sndHandle);
return;
}
else
{
GetModuleFileName(sndHandle, modName,
MAX_PATH);
cout << "Using DLL: " << modName
<< endl;
// make the beeps
MultiHonk(iterations);
// release the DLL
FreeLibrary(sndHandle);
}
}
}
// snd.cpp
#include <windows.h>
#include "snd.h"
BOOL WINAPI SndEntryPoint(HINSTANCE dllHandle,
DWORD reason, LPVOID situation)
{
CHAR buf[80];
switch(reason)
{
case DLL_PROCESS_ATTACH:
if (situation)
wsprintf(buf, "DLL statically loaded.");
else
wsprintf(buf, "DLL dynamically loaded.");
break;
case DLL_THREAD_ATTACH:
wsprintf(buf, "New thread starting.");
break;
case DLL_PROCESS_DETACH:
if (situation)
wsprintf(buf, "DLL released by system.");
else
wsprintf(buf, "DLL released by program.");
break;
case DLL_THREAD_DETACH:
wsprintf(buf, "Thread terminating.");
break;
default:
return FALSE;
}
MessageBox(NULL, buf, "DLL Info",
MB_OK | MB_ICONINFORMATION);
return TRUE;
}
void MultiHonk(DWORD iterations)
{
UINT i;
for (i=0; i<iterations; i++)
{
Beep(200, 50);
Sleep(1000);
}
}
// stack.h
typedef struct _stacknode
{
int data;
struct _stacknode *next;
} stacknode, *stack;
extern "C"
{
void init(stack *s);
void push(stack *s, int i);
int pop (stack *s);
void destroy(stack *s);
}
// stack.cpp
#include <windows.h>
#include "stack.h"
void init(stack *top)
{
*top=0;
}
void push(stack *top, int value)
{
stacknode *temp;
temp = (stacknode *) GlobalAlloc(GPTR,
sizeof stacknode);
temp->data = value;
temp->next = *top;
*top = temp;
}
int pop(stack *top)
{
stacknode *temp;
int value;
if (*top == 0)
return 0;
temp = *top;
value = (*top)->data;
*top = (*top)->next;
delete temp;
return value;
}
void destroy(stack *top)
{
while (*top != 0);
pop(top);
}