Tuesday, July 14, 2009

DLL - Programming basics

Points to be noted:
  1. __declspec() : Declares the following class or function to be exported/imported (mainly). For example, __declspec(dllexport) void func() {} implies, func() is exported for applications use
  2. Wondering, when my app could not able to get the handle of exported APIs when the .h file of DLL had the definitions. When i moved the definitions to .cpp file of DLL project, my app could get the handle successfully
  3. If using visual studio, you can use "Pre-Build Event" (under Build Events) to copy the DLL to the app folder
  4. When using LoadLibrary call, due to UNICODE probs, the dll may not get loaded. Hence use _T casting like hHandle = LoadLibrary( _T ( "mydll.dll" ) );
  5. To check the "sections" contained in the DLL, open the Visual Studio command prompt (not the normal windows prompt) and go to the directory which has the dll file, and type dumpbin /exports mydll.dll
===============================
DLL CODE
===============================

/*
* This is .h file of a DLL
*/
#include <windows.h>

/* If we try to export all the APIs to the app by preceding each API with __declspec(dllexport)
* then the corresponding API will always be exported even when app does not require it.
* For this very reason, DLL developer tries to export it from his project, where as the
* app developer, will try to import it in his code. */

#if defined EXPORT_DIR
#define DECLAPI __declspec( dllexport )
#else
#define DECLAPI __declspec( dllimport )
#endif

/* Tell the compiler that its OK to use these APIs in either C or C++ */
extern "C"
{
DECLAPI int addition( int a, int b );
DECLAPI int multiply( int a, int b );
}

/*
* This is .cpp file of DLL project
*/

#include "mydll.h"

/* [Important]: Define this macro to try to export the APIs (even though not catched by apps) */
#define EXPORT_DIR

extern "C"
{
DECLAPI int addition ( int a, int b ) { return a + b; }
DECLAPI int multiply ( int a, int b ) { return a * b; }
}

================================
APP Code
================================
/*
* This is the application which uses the DLLs
*/

#include <iostream>
#include <windows.h>

typedef int ( *Addition ) ( int, int );
typedef int ( *Multiply ) ( int, int );

int main()
{
HINSTANCE hInstance;
Addition additionPtr;
Multiply multiplyPtr;

hInstance = LoadLibrary( _T ( "mydll.dll" ) );
if( hInstance )
{
additionPtr = ( Addition ) GetProcAddress ( hInstance, "addition" );
multiplyPtr = ( Multiply ) GetProcAddress ( hInstance, "multiply" );

if( additionPtr )
printf( "DLL addition called and sum: %d.\n", additionPtr( 10, 5 ) );
if( multiplyPtr )
printf( "DLL multiply called and sum: %d.\n", multiplyPtr( 10, 5 ) );

FreeLibrary( hInstance );
}
else
{
printf( "Failed to load mydll.dll!!!!..\n" );
}
return 0;
}

No comments:

Post a Comment