Saturday, February 12, 2011

DLL

1. Creating a Simple Dynamic-Link Library

The following example is the source code needed to create a simple DLL, Myputs.dll. It defines a simple string-printing function called myPuts. The Myputs DLL does not define an entry-point function, because it is linked with the C run-time library and has no initialization or cleanup functions of its own to perform.
To build the DLL, follow the directions in the documentation included with your development tools.
For an example that uses myPuts, see Using Load-Time Dynamic Linking or Using Run-Time Dynamic Linking.

// The myPuts function writes a null-terminated string to
// the standard output device.
 
// The export mechanism used here is the __declspec(export)
// method supported by Microsoft Visual Studio, but any
// other export method supported by your development
// environment may be substituted.
 
 
#include <windows.h>
 
#define EOF (-1)
 
#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif
 
__declspec(dllexport) int __cdecl myPuts(LPWSTR lpszMsg)
{
    DWORD cchWritten;
    HANDLE hConout;
    BOOL fRet;
 
    // Get a handle to the console output device.

    hConout = CreateFileW(L"CONOUT$",
                         GENERIC_WRITE,
                         FILE_SHARE_WRITE,
                         NULL,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         NULL);

    if (INVALID_HANDLE_VALUE == hConout)
        return EOF;
 
    // Write a null-terminated string to the console output device.
 
    while (*lpszMsg != L'\0')
    {
        fRet = WriteConsole(hConout, lpszMsg, 1, &cchWritten, NULL);
        if( (FALSE == fRet) || (1 != cchWritten) )
            return EOF;
        lpszMsg++;
    }
    return 1;
}
 
#ifdef __cplusplus
}
#endif  

2.Using Load-Time Dynamic Linking

After you have created a DLL, you can use the functions it defines in an application. The following is a simple console application that uses the myPuts function exported from Myputs.dll (see Creating a Simple Dynamic-Link Library).
Because this example calls the DLL function explicitly, the module for the application must be linked with the import library Myputs.lib. For more information about building DLLs, see the documentation included with your development tools.

#include <windows.h> 

extern "C" int __cdecl myPuts(LPWSTR);   // a function from a DLL

int main(VOID) 
{ 
    int Ret = 1;

    Ret = myPuts(L"Message sent to the DLL function\n"); 
    return Ret;
}


3. Using Run-Time Dynamic Linking

You can use the same DLL in both load-time and run-time dynamic linking. The following example uses the LoadLibrary function to get a handle to the Myputs DLL (see Creating a Simple Dynamic-Link Library). If LoadLibrary succeeds, the program uses the returned handle in the GetProcAddress function to get the address of the DLL's myPuts function. After calling the DLL function, the program calls the FreeLibrary function to unload the DLL.
Because the program uses run-time dynamic linking, it is not necessary to link the module with an import library for the DLL.
This example illustrates an important difference between run-time and load-time dynamic linking. If the DLL is not available, the application using load-time dynamic linking must simply terminate. The run-time dynamic linking example, however, can respond to the error.

// A simple program that uses LoadLibrary and 
// GetProcAddress to access myPuts from Myputs.dll. 
 
#include <windows.h> 
#include <stdio.h> 
 
typedef int (__cdecl *MYPROC)(LPWSTR); 
 
VOID main(VOID) 
{ 
    HINSTANCE hinstLib; 
    MYPROC ProcAdd; 
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
 
    // Get a handle to the DLL module.
 
    hinstLib = LoadLibrary(TEXT("MyPuts.dll")); 
 
    // If the handle is valid, try to get the function address.
 
    if (hinstLib != NULL) 
    { 
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 
 
        // If the function address is valid, call the function.
 
        if (NULL != ProcAdd) 
        {
            fRunTimeLinkSuccess = TRUE;
            (ProcAdd) (L"Message sent to the DLL function\n"); 
        }
        // Free the DLL module.
 
        fFreeResult = FreeLibrary(hinstLib); 
    } 

    // If unable to call the DLL function, use an alternative.
    if (! fRunTimeLinkSuccess) 
        printf("Message printed from executable\n"); 
}


Related Topics

Run-Time Dynamic Linking

 

No comments: