Sunday 29 May 2011

The Recursive Paradigm

The Recursive Paradigm

if (test for a simple case)
{
  Compute and return the simple solution without using recursion.
}
else
{
  Divide the problem into one or more subproblems that have the same form.
  Solve each of the problems by calling this method recursively.
  Return the solution from the results of the various subproblems.
}

Finding a recursive solution is mostly a matter of figuring out how to break it down so that it fits the paradigm.When you do so, you must do two things:
1. Identify simple cases that can be solved without recursion.
2. Find a recursive decomposition that breaks each instance of the problem into simpler sub problems of the sametype, which you can then solve by applying the method recursively.

Tuesday 17 May 2011

Diffrence between Copy Constructor and the overloading Assignment operator overloading

Assignment Operator is used to copy values of one object to another existing object of the same class. The pre requisite for assignment operator to be called is the LHS of the assignment must already be allocated.


template <class T>
class SampleClass {
        T var1;
        public:
                SampleClass() { }//default constructor 
                SampleClass(T value): var1(value){}//constructor
                ~SampleClass() {} //destructor
                SampleClass& operator= (SampleClass &sorce){ //Assignment operator oveloaded
                        if(this = &source){
                        //Self assign Should not happen - will land up in deep shit 
if deep copying is implemted.
//however the example takes up shallow copying as member
attributes are all static.
}else{ var1 = source.var1; } return *this; } } SampleClass<int> obj1; //calls defaut copy constructor SampleClass<int> obj2(5);//calls constructor SampleClass<int> obj3 = obj2; //calls copy constructor obj1 = obj3; //calls the overloaded assignment operator.

In the above sample the third statement uses the = operator but the overloaded assignment operator function is not called as the object "obj3" doesn't exist, hence the copy constructor is called. The copy constructor creates a new object and then copies the value of the source object to the newly allocated object.

The purpose of the copy constructor and the assignment operator are almost equivalent — both copy one object to another. However, the assignment operator copies to existing objects, and the copy constructor copies to newly created objects.

There are three general cases where a copy constructor is called instead of an assignment operator

i) When instantiating one object and initializing it with values from another object.
ii)When passing an object by value.
iii) When an object is returned from a function by value

Monday 16 May 2011

Syntax highlighting in your blog for C++(can be extended to other programming languages as well)

Its just been a few days since I started blogging and one major road block i faced was being able to provide syntax highlighting for various code snippets in my blog. The monochrome text often looks boring and and also so unwelcoming to the readers. So I decide to do some goggling on syntax highlighting for blogs. As usual Google didn't disappoint me when it comes to giving results, what disappointed me is none of them were apt and feasible for me.Just finding no luck i just paused my (RE)Search :P on this topic and continued to blog it the way the blogger allows me to.

It Struck to me that gvim supports syntax highlighting and also allows us to export the code in format of html. At last i found the way to achieve it. if you have read through all the above crap here is a brief tutorial.

I assume u can Google and download gvim.

Step1: Write your code or paste your code onto the editor window.

Step2: Choose a color scheme(Step2 and Step3 are interchangeable)

Step3: Turn on the Syntax highlighting for this file.

Step4:You can now see the code with syntax highlighting

Step5: Generate an HTML file for the code file.

Step6:You now have the html with styling for the syntax highlighted code file of yours.


Step7:Exclude the html and the body tags, now copy the CSS styles and the contents of the pre tag to the blog's Editor.Go to Edit HTML option and paste the copied styling and tags in the necessary location of the div tag. You are good to go with your syntax highlighted posts. 

Sunday 15 May 2011

Intoduction and implemntation to Smart Pointer in C++


Smart  Pointer in C++(in genral Computer Science) is an Object which simulates a pointer. As the name suggests Smart Pointers are Smart i.e they have all the flexibility of a pointer and also have the features of a object like constructors and destructors. The features of an Object can be used to introduce the automatic garbage collection for a Smart Pointer and also retaining all the features of a pointer.Smart isn't it?

Use of smart pointers helps us solve all the conventional problems we had to takecare when programming with pointers.It also helps prevent memory leaks and danglling pointers.

The below code provides an simple implementation of smart pointer class and how it can be used.
The code has been written using templates to make the class SmartPointer genric and usable for multiple data types. The use of the SmartPointer has been explained by taking simple float data type. But the SmartPointer implementation is not just restricted to the basic data types it can be used for custom class objects aswell.

 1 
 2 template <class T>
 3 class SmartPointer
 4 {
 5 private:
 6         T *pointerData;
 7 
 8 public:
 9         SmartPointer(T* pData) //constructor 
10         {
11                 pointerData = pdata;
12         }
13 
14         ~SmartPointer() //Destructor
15         {
16 
17                 //isValid() helps us prevent the destructor being called by 
multiple refrence for the same pointer.
18                 if(isValid())
19                 {
20                         delete pointerData;
21                         release(); //pointerData has to be made Null for 
isValid() function to serve its purpose.
22                 }
23         }
24 
25         T& operator* ()
26         {
27                 return *pointerData;
28         }
29 
30         T* operator-> ()
31         {
32                 return pointerData;
33         }
34 
35         bool isValid()
36         {
37                 //its usually a good practice to use null on LHS than RHS,
 as it avoids unintentionnal null assignment.
38                 if(NULL != pointerData)
39                 {
40                         return true;
41                 }
42                 else
43                 {
44                         return false;
45                 }
46         }
47 
48         T* getPointer()
49         {
50                 return *pointerData;
51         }
52 
53         void release()
54         {
55                 pointerData = NULL;
56         }
57 
58 }
59 
60 int main()
61 {
62         //Declare a float and dynamically allocate the object using the 
smart pointer class
63         SmartPointer<float> floatPointer(new float);
64 
65         *floatPointer = 3.4; //Value is assigned to the above declared float
66 
67         return 0;
68 }//The smart pointer is out of scope and the stack unwinds calling the
 destructor of SmartPointer class. 
69   

More to come Smart Pointers with Reference counting(coding it now :P)

Something worth noting when using Smart pointers in ur design is Smart pointers objects shouldn't be stored in STL containers. The reason being The C++ Standard, it  says that an STL element must be "copy-constructable" and "assignable." This means you will be able to safely assign or copy one object to another and get two independent and logically identical copies i.e  the state of the original object shouldn't change when it is copied to a target object. but in the case of Smart pointers copying or assigning one smartpointer to another makes changes to the original and also the changes reflect from the copy(Obvious as both refer to same object). 

Saturday 14 May 2011

C++ Points to remember

1) A refrence should always be initialized when its declared.

2) A constant data member in the class should always be initialized in the Constructor of the class and not in the defnition of the class.

3) A static member of the class should also be defined once outside the class.
    Eg: class A
         {
           public:
           static int a;
           A(){a=10;}
         };

         int main()
        {
          A b;
          printf("%d", b.a);
          return 0;
        }
The above code will not compile successfully as static datamember of class A is not defined outside the class. "int A::a;" has to  be added after the class Declaration.

4) Its leagal to call member functions from destructor of a Class, but care must be taken not to call functions which already have been freed. The called member functions should not lead to any exceptions being triggred as it will lead to calling the destructor of the class or this destructor itself might have been triggred by a Exception.

5) Static member functions of a class are actully Global functions with its namespace as the class.

6)If a forward declaration is made, but the function is never called, the program will compile and run fine. However, if a forward declaration is made, the function is called, but the program never defines the function, the program will compile okay, but the linker will complain that it can’t resolve the function call.

7)Angle brackets are used to including header files which came from the compiler and the quotes are used in including headers within the project

8) While C allows the main() function to return a void, C++ strictly about the return type of the main() and doesn't allow a void return type.

C++ Puzzles / Interview questions

Here are a few C++ puzzles which are aimed at helping one in understanding C++ better.

1)Declaring a variable
    const char *var1="String";
    Which of the operations are valid on var1?
      1)var1="Hello";
      2)*var1='H';

Answer:
When var1 is declared as a const char *var1="String"; you are specifying var1 as pointer to a character constant i.e the contents of the location pointed by var1 are constant. So you can not change the contents of the location pointed to by *var1. The assignment *Var1='H' attempts to change the Content pointed by the pointer var1. But with the assignment var1="Hello"; the contents of location pointed by var1 is not changing but the var1 is made to point to a whole new location i.e location of String Hello.

2)Similar to above example
   char* const var2 = "String";

  1)var2="Hello"
  2)*var2='H';

Now var2 is declared as a constant pointer to character. var2 always points to the same memory location. however the value held by the memory location can be updated. Hence the var2="Hello"; is wrong and *var2='H';

3) Will this program compile successfully ?

void f(){};
void g() {return f();}
main()
{
g();
}

Answer:
No.
void g() means that it can not return anything-not even a void value. Here return f() means it is trying to return void.

Thursday 5 May 2011

If Java does not have pointers, why is there a "NullpointerException"?

Its a common statement we keep hearing that Java doesn't have pointers. Well its actually untrue, Java has pointers but is never referred to has pointers and we cannot manipulate them.


A simple example can explain how pointers are used in Java.


Object a = new Object(), b=a;


In the above statement a,b are pointers to a single object in memory. Operations performed on a or b effects the same object.


Java has a set of Primitive types for whom this behavior  doesn't apply. Consider


int i1 =10, i2= i1;
System.out.println(" i1 ="+i1+"i2="+i2) ;
i2=6;
System.out.println(" i1 ="+i1+"i2="+i2) ;

The primitive variable i2 initially holds the copy of the value held by variable i1. Changing value of i1 or i2 will not effect the values of each other. For a Java VM  i1 and i2 are two different 32 bit memory locations. One exception to this is arrays of primitive types. Behavior of arrays are similar to what I'll be explain in the below example


Now consider:


public class Value{int val1;}
Value v1=new Value(10), v2=v1;
System.out.println("v1 ="+v1.val1+"v2="+v2.val1) ;
v2.val1=100;
System.out.println("v1 ="+v1.val1+"v2="+v2.val1) ;


v2 has a copy of the address pointed by v1, hence v1 and v2 point to the same object. Changes made to object of class Value using v1 can also be accessed using v2.

Handling Multiple Return values in JAVA (C++ aswell :-)

After lot of Goggling and reading the best solution i could find for this problem was at http://javatuples.com/. The tuples implementation provides us utilities for handling scenarios where we would need to return multiple return types from a Java function (Basically its a kind of Wrapper implementation for the return objects). A similar implementation can be used in C++ by developing a template class to hold multiple types of data and return that class object, but C++ gives us total flexibility to use pointers hence we can achieve it even with out an additional Class implementation.

I'm still a newbie so people pour in your suggestions if there are better ways to achieve the same.

Wednesday 4 May 2011

Who's who of the World of Programming.

C++ DLL


DLL

Dynamic linking is a mechanism that links applications to libraries at run time. The libraries remain in their own files and are not copied into the executable files of the applications. DLLs link to an application when the application is run, rather than when it is created. DLLs may contain links to other DLLs.

Advantages of DLL

  • Uses fewer resources
The advantage of DLL files is that, because they don't get loaded into random access memory (RAM) together with the main program, space is saved in RAM. When and if a DLL file is needed, then it is loaded and run. For example, as long as a user of Microsoft Word is editing a document, the printer DLL file does not need to be loaded into RAM. If the user decides to print the document, then the Word application causes the printer DLL file to be loaded and run.
  • Promotes modular architecture
A DLL helps promote developing modular programs. This helps you develop large programs that require multiple language versions or a program that requires modular architecture. An example of a modular program is an accounting program that has many modules that can be dynamically loaded at run time.
  • Eases deployment and installation
When a function within a DLL needs an update or a fix, the deployment and installation of the DLL does not require the program to be relinked with the DLL. Additionally, if multiple programs use the same DLL, the multiple programs will all benefit from the update or the fix. This issue may more frequently occur when you use a third-party DLL that is regularly updated or fixed.
Applications and DLLs can link to other DLLs automatically if the DLL linkage is specified in the IMPORTS section of the module definition file as part of the compile or you can explicitly load them using the Windows LoadLibrary function.
First we will discuss the issues and the requirements that you should consider when you develop your own DLLs.

Types of DLLs

When you load a DLL in an application, two methods of linking let you call the exported DLL functions. The two methods of linking are load-time dynamic linking and run-time dynamic linking.
Load-time dynamic linking
In load-time dynamic linking, an application makes explicit calls to exported DLL functions like local functions. To use load-time dynamic linking, provide a header (.h) file and an import library (.lib) file when you compile and link the application. When you do this, the linker will provide the system with the information that is required to load the DLL and resolve the exported DLL function locations at load time.
Run-time dynamic linking
In run-time dynamic linking, an application calls either the LoadLibrary function or the LoadLibraryEx function to load the DLL at run time. After the DLL is successfully loaded, you use the GetProcAddress function to obtain the address of the exported DLL function that you want to call. When you use run-time dynamic linking, you do not need an import library file.
The following list describes the application criteria for when to use load-time dynamic linking and when to use run-time dynamic linking:
  • Startup performance
If the initial startup performance of the application is important, you should use run-time dynamic linking.
  • Ease of use
In load-time dynamic linking, the exported DLL functions are like local functions. This makes it easy for you to call these functions.
  • Application logic
In run-time dynamic linking, an application can branch to load different modules as required. This is important when you develop multiple-language versions.

The DLL entry point

When you create a DLL, you can optionally specify an entry point function. The entry point function is called when processes or threads attach themselves to the DLL or detached themselves from the DLL. You can use the entry point function to initialize data structures or to destroy data structures as required by the DLL. Additionally, if the application is multithreaded, you can use thread local storage (TLS) to allocate memory that is private to each thread in the entry point function. The following code is an example of the DLL entry point function.

BOOL APIENTRY DllMain(
HANDLE hModule,        // Handle to DLL module
                    DWORD ul_reason_for_call,
                    LPVOID lpReserved ) // Reserved
{
                    switch ( ul_reason_for_call )
                    {
                                         case DLL_PROCESS_ATTACHED:
                                         // A process is loading the DLL.
                                         break;
                                         case DLL_THREAD_ATTACHED:
                                         // A process is creating a new thread.
                                         break;
                                         case DLL_THREAD_DETACH:
                                         // A thread exits normally.
                                         break;
                                         case DLL_PROCESS_DETACH:
                                         // A process unloads the DLL.
                                         break;
                    }
                    return TRUE;
}
When the entry point function returns a FALSE value, the application will not start if you are using load-time dynamic linking. If you are using run-time dynamic linking, only the individual DLL will not load.
The entry point function should only perform simple initialization tasks and should not call any other DLL loading or termination functions. For example, in the entry point function, you should not directly or indirectly call the LoadLibrary function or the LoadLibraryEx function. Additionally, you should not call theFreeLibrary function when the process is terminating.
WARNING: In multithreaded applications, make sure that access to the DLL global data is synchronized (thread safe) to avoid possible data corruption. To do this, use TLS to provide unique data for each thread.

Exporting DLL functions

To export DLL functions, you can either add a function keyword to the exported DLL functions or create a module definition (.def) file that lists the exported DLL functions.
To use a function keyword, you must declare each function that you want to export with the following keyword:

 __declspec(dllexport)
To use exported DLL functions in the application, you must declare each function that you want to import with the following keyword:

 __declspec(dllimport)
Typically, you would use one header file that has a define statement and an ifdef statement to separate the export statement and the import statement.
You can also use a module definition file to declare exported DLL functions. When you use a module definition file, you do not have to add the function keyword to the exported DLL functions. In the module definition file, you declare the LIBRARY statement and the EXPORTS statement for the DLL. The following code is an example of a definition file.

// SampleDLL.def
//
LIBRARY "sampleDLL"
 
EXPORTS
  HelloWorld

 

How to Write DLL

Write Sample DLL

In Microsoft Visual C++ 6.0, you can create a DLL by selecting either the Win32 Dynamic-Link Library project type or the MFC AppWizard (dll) project type.
The following code is an example of a DLL that was created in Visual C++ by using the Win32 Dynamic-Link Library project type.

// SampleDLL.cpp
//
 
#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"
 
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                                                                                                       )
{
    return TRUE;
}
 
void HelloWorld()
{
   MessageBox( NULL, TEXT("Hello World"), 
                                                             TEXT("In a DLL"), MB_OK);
}


// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H
 
#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif
 
#endif

Calling Sample DLL in your Program

The following code is an example of a Win32 Application project that calls the exported DLL function in the SampleDLL DLL.

// SampleApp.cpp 
//
 
#include "stdafx.h"
#include "sampleDLL.h"
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{                   
                    HelloWorld();
                    return 0;
}
NOTE: In load-time dynamic linking, you must link the SampleDLL.lib import library that is created when you build the SampleDLL project.
In run-time dynamic linking, you use code that is similar to the following code to call the SampleDLL.dll exported DLL function.

...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;
 
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
    HelloWorld = (DLLPROC) GetProcAddress(hinstDLL,
                                                                                                       "HelloWorld");
    if (HelloWorld != NULL)
        (HelloWorld);
 
    fFreeDLL = FreeLibrary(hinstDLL);
}
...
When you compile and link the SampleDLL application, the Windows operating system searches for the SampleDLL DLL in the following locations in this order:
1.        The application folder
2.        The current folder
3.        The Windows system folder
NOTE: The GetSystemDirectory function returns the path of the Windows system folder.
4.        The Windows folder
NOTE: The GetWindowsDirectory function returns the path of the Windows folder.

In order for a DLL to be used, it has to be registered by having appropriate references entered in the Registry. It sometimes happens that a Registry reference gets corrupted and the functions of the DLL cannot be used anymore. The DLL can be re-registered by opening Start-Run and entering the command

regsvr32 somefile.dll
This command assumes that somefile.dll is in a directory or folder that is in the PATH. Otherwise, the full path for the DLL must be used. A DLL file can also be unregistered by using the switch "/u" as shown below.

regsvr32 /u somefile.dll
This can be used to toggle a service on and off.

Tools for Windows DLL

Several tools are available to help you troubleshoot DLL problems. The following tools are some of these tools.
Dependency Walker
The Dependency Walker tool ( depends.exe ) can recursively scan for all dependent DLLs that are used by a program. When you open a program in Dependency Walker, Dependency Walker performs the following checks:
  • Dependency Walker checks for missing DLLs.
  • Dependency Walker checks for program files or DLLs that are not valid.
  • Dependency Walker checks that import functions and export functions match.
  • Dependency Walker checks for circular dependency errors.
  • Dependency Walker checks for modules that are not valid because the modules are for a different operating system.
By using Dependency Walker, you can document all the DLLs that a program uses. This may help prevent and correct DLL problems that may occur in the future. Dependency Walker is located in the following directory when you install Microsoft Visual Studio 6.0:

drive\Program Files\Microsoft Visual Studio\Common\Tools

DLL Universal Problem Solver
The DLL Universal Problem Solver (DUPS) tool is used to audit, compare, document, and display DLL information. The following list describes the utilities that make up the DUPS tool:
  • Dlister.exe
    This utility enumerates all the DLLs on the computer and logs the information to a text file or to a database file.
  • Dcomp.exe
    This utility compares the DLLs that are listed in two text files and produces a third text file that contains the differences.
  • Dtxt2DB.exe
    This utility loads the text files that are created by using the Dlister.exe utility and the Dcomp.exe utility into the dllHell database.
  • DlgDtxt2DB.exe
    This utility provides a graphical user interface (GUI) version of the Dtxt2DB.exe utility.


Example 1 : Working from the command line

Now we make a one-line DLL. Here's the source:

extern "C" __declspec(dllexport) void myfun(int * a){*a = - *a; }
Save this to file myfun.cpp and compile it from the DOS prompt with

cl -LD myfun.cpp
The -LD switch says to generate a DLL. Next we make an executable which calls the DLL. Here's the source:

#include iostream.h
 
extern C __declspec(dllimport) void myfun ( int * a);
 
void main(void)
{
 int a = 6;
 int b = a;
 myfun(&b);
 
 cout << '-' << a << " is " << b << "! \n";
}
Save this to file main.cpp. Then compile and link from the command prompt with

cl main.cpp /link myfun.lib
Execute it from the command line (just type 'main') and watch with awe!

Example 2 : Using VC++ IDE to create DLL

The DLL entry point

When you create a DLL, you can optionally specify an entry point function. The entry point function is called when processes or threads attach themselves to the DLL or detached themselves from the DLL. You can use the entry point function to initialize data structures or to destroy data structures as required by the DLL. Additionally, if the application is multithreaded, you can use thread local storage (TLS) to allocate memory that is private to each thread in the entry point function. The following code is an example of the DLL entry point function.

BOOL APIENTRY DllMain(
HANDLE hModule,        // Handle to DLL module
                    DWORD ul_reason_for_call,
                    LPVOID lpReserved ) // Reserved
{
                    switch ( ul_reason_for_call )
                    {
                                         case DLL_PROCESS_ATTACHED:
                                         // A process is loading the DLL.
                                         break;
                                         case DLL_THREAD_ATTACHED:
                                         // A process is creating a new thread.
                                         break;
                                         case DLL_THREAD_DETACH:
                                         // A thread exits normally.
                                         break;
                                         case DLL_PROCESS_DETACH:
                                         // A process unloads the DLL.
                                         break;
                    }
                    return TRUE;
}
When the entry point function returns a FALSE value, the application will not start if you are using load-time dynamic linking. If you are using run-time dynamic linking, only the individual DLL will not load.
The entry point function should only perform simple initialization tasks and should not call any other DLL loading or termination functions. For example, in the entry point function, you should not directly or indirectly call the LoadLibrary function or the LoadLibraryEx function. Additionally, you should not call the FreeLibraryfunction when the process is terminating.
WARNING: In multithreaded applications, make sure that access to the DLL global data is synchronized (thread safe) to avoid possible data corruption. To do this, use TLS to provide unique data for each thread.

Exporting DLL functions

To export DLL functions, you can either add a function keyword to the exported DLL functions or create a module definition (.def) file that lists the exported DLL functions.
To use a function keyword, you must declare each function that you want to export with the following keyword:

 __declspec(dllexport)
To use exported DLL functions in the application, you must declare each function that you want to import with the following keyword:

 __declspec(dllimport)
Typically, you would use one header file that has a define statement and anifdef statement to separate the export statement and the import statement.
You can also use a module definition file to declare exported DLL functions. When you use a module definition file, you do not have to add the function keyword to the exported DLL functions. In the module definition file, you declare the LIBRARYstatement and the EXPORTS statement for the DLL. The following code is an example of a definition file.

// SampleDLL.def
//
LIBRARY "sampleDLL"
 
EXPORTS
  HelloWorld

Write Sample DLL

In Microsoft Visual C++ 6.0, you can create a DLL by selecting either the Win32 Dynamic-Link Library project type or the MFC AppWizard (dll) project type.
The following code is an example of a DLL that was created in Visual C++ by using the Win32 Dynamic-Link Library project type.

// SampleDLL.cpp
//
 
#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"
 
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                                                                                                       )
{
    return TRUE;
}
 
void HelloWorld()
{
   MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}


// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H
 
#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif
 
#endif

Calling Sample DLL in your Program

The following code is an example of a Win32 Application project that calls the exported DLL function in the SampleDLL DLL.

// SampleApp.cpp 
//
 
#include "stdafx.h"
#include "sampleDLL.h"
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{                   
                    HelloWorld();
                    return 0;
}
NOTE: In load-time dynamic linking, you must link the SampleDLL.lib import library that is created when you build the SampleDLL project.
In run-time dynamic linking, you use code that is similar to the following code to call the SampleDLL.dll exported DLL function.

...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;
 
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
    HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");
    if (HelloWorld != NULL)
        (HelloWorld);
 
    fFreeDLL = FreeLibrary(hinstDLL);
}
...
When you compile and link the SampleDLL application, the Windows operating system searches for the SampleDLL DLL in the following locations in this order:
1.        The application folder
2.        The current folder
3.        The Windows system folder
NOTE: The GetSystemDirectory function returns the path of the Windows system folder.
4.        The Windows folder
NOTE: The GetWindowsDirectory function returns the path of the Windows folder.