Load DLL At Runtime
A minimal pair of programs — a DLL exporting two functions and a console app that loads it at runtime with LoadLibrary/GetProcAddress.
The classic dynamic-loading pattern in its smallest form. Square.Dll exports an int function and a string function plus the standard LibMain (the old-style DllMain); the loader calls LoadLibrary, resolves each export with GetProcAddress into a FARPROC, invokes them, and finishes with FreeLibrary. Use this shape whenever you need to plug optional functionality into a running program - plugin systems, version-tolerant feature detection, or calling code you did not link against at build time.
// Square.C - the DLL
#include <Windows.H>
#include <WindowsX.H>
#include <Stdio.H>
#include <Stdlib.H>
#include <TChar.H>
#include <ShlWapi.H>
BOOL WINAPI __declspec(dllexport) LibMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
__declspec(dllexport) int Intenger (int A)
{
return A*A;
}
__declspec(dllexport) char *String ()
{
return "Return String";
}
// LoadDLL.C - the host application
#include <Windows.H>
#include <WindowsX.H>
#include <Stdio.H>
#include <Stdlib.H>
#include <TChar.H>
#include <ShlWapi.H>
HANDLE DLL_Handle;
FARPROC DLL_CallBack;
int main()
{
DLL_Handle = LoadLibrary("Square.Dll");
if(!DLL_Handle)
{
printf("Could Not Load DLL.\n");
return 0;
}
DLL_CallBack = GetProcAddress(DLL_Handle,"_Intenger");
if(!DLL_CallBack)
{
printf("Could Not Load DLL Function.\n");
return 0;
}
printf("Intenger = %d\n",DLL_CallBack(5));
DLL_CallBack = GetProcAddress(DLL_Handle,"_String");
if(!DLL_CallBack)
{
printf("Could Not Load DLL Function.\n");
return 0;
}
printf("String = %s\n",DLL_CallBack());
// Must FreeLibrary And Exit Thread.
FreeLibrary(DLL_Handle);
ExitThread(0);
// Or Do It All In One Call
// FreeLibraryAndExitThread(DLL_Handle,0);
return 0;
}
Two era-specific details: the underscore-prefixed names ("_Intenger") are the cdecl name-decorated exports from 32-bit Borland/VC builds - modern MSVC exports resolve without the leading underscore unless you add extern "C". And ExitThread is used because this predates the habit of just returning from main; today FreeLibrary followed by a normal exit is all you need.