[ Home | Syllabus | Course Notes | Assignments | Search]
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); }