1. 程式人生 > >LoadLibrary方式載入DLL模版程式碼

LoadLibrary方式載入DLL模版程式碼

本文貼出了我之前寫的讀取身份證資訊的程式碼。程式碼使用LoadLibrary函式載入DLL。

旨在以後寫動態載入DLL的程式碼時,參考此程式碼。

程式碼如下:

IDCardRead.h

#ifndef _ID_CARD_READ_H_
#define _ID_CARD_READ_H_

typedef int (WINAPI *WLT_GetBmp)(char *sWltFile, int nType);


typedef int (WINAPI *SDT_OpenPort)(int nPort);
typedef int (WINAPI *SDT_ClosePort)(int nPort);
typedef int (WINAPI *SDT_StartFindIDCard)(int nPort, unsigned char *pRAPDU, int nIfOpen);
typedef int (WINAPI *SDT_SelectIDCard)(int nPort, unsigned char *pRAPDU, int nIfOpen);
typedef int (WINAPI *SDT_ReadBaseMsg)(int nPort, unsigned char *pCHMsg, unsigned int *pCHMsgLength,
                                      unsigned char *pPHMsg, unsigned int *pPHMsgLength, int nIfOpen);



typedef struct _ID_CARD_INFORMATION_
{
    wchar_t     szName[32];
    wchar_t     szGender[2];
    wchar_t     szNation[32];
    wchar_t     szBirth[32];
    wchar_t     szAddress[128];
    wchar_t     szIDCode[32];
    wchar_t     szAuthority[32];
    wchar_t     szIssueDay[32];
    wchar_t     szExpiryDay[32];
    wchar_t     szPhotoPath[128];
}ID_CARD_INFORMATION;

class IDCardRead
{
public:
    /**
     * return 0;  success
     * return -1; sdtapi.dll load failed
     * return -2; WltRS.dll load failed
     * return -3; load function in sdtapi.dll failed
     * return -4; load function in WltRS.dll failed
     */
    static int Initialize();
    static void Uninitialize();

    /**
     * return 0;  success
     * return -1; Init parameter is not right, may be Initialize function return failed
     * return -2; connect device failed, may be id card reader device is not connected with computer.
     * 
     */
    int ConnectDevice();

    /**
     * return 0;  success
     * return -1; Init parameter is not right, may be Initialize function return failed
     * return -2; disconnect device failed, may be device is not connect or ConnectDevice function is not
     *            called before.
     * 
     */
    int DisconnectDevice();

    /**
     * return 0;  success
     * return -1; Init parameter is not right, may be Initialize function return failed
     * return -2; detect card failed. no card.
     * return -3; find card, but select card failed
     * return -4; device is not connect
     * 
     */
    int DetectCard();

    //trim right space;
    void TrimRight(wchar_t *sInput);

    void GetNationFromCode(wchar_t *sNation, int nNationCode);

    /**
     * return 0;  success
     * return -1; Init parameter is not right, may be Initialize function return failed
     * return -2; pInfo is NULL
     * return -3; device is not connect
     * return -4; read base information failed
     */
    int GetCardInformation(ID_CARD_INFORMATION *pInfo);
public:
    IDCardRead();
    ~IDCardRead();
private:
    static WLT_GetBmp               ms_fpWLT_GetBmp;
    static SDT_OpenPort             ms_fpSDT_OpenPort;
    static SDT_ClosePort            ms_fpSDT_ClosePort;
    static SDT_StartFindIDCard      ms_fpSDT_StartFindIDCard;
    static SDT_SelectIDCard         ms_fpSDT_SelectIDCard;
    static SDT_ReadBaseMsg          ms_fpSDT_ReadBaseMsg;

    static HMODULE                  ms_hSDTAPI;
    static HMODULE                  ms_hWltRS;

    int                             m_nDevicePort;
};

#endif//_ID_CARD_READ_H_

IDCardRead.cpp
#include "stdafx.h"
#include "IDCardRead.h"

WLT_GetBmp               IDCardRead::ms_fpWLT_GetBmp = NULL;
SDT_OpenPort             IDCardRead::ms_fpSDT_OpenPort = NULL;
SDT_ClosePort            IDCardRead::ms_fpSDT_ClosePort = NULL;
SDT_StartFindIDCard      IDCardRead::ms_fpSDT_StartFindIDCard = NULL;
SDT_SelectIDCard         IDCardRead::ms_fpSDT_SelectIDCard = NULL;
SDT_ReadBaseMsg          IDCardRead::ms_fpSDT_ReadBaseMsg = NULL;

HMODULE                  IDCardRead::ms_hSDTAPI = NULL;
HMODULE                  IDCardRead::ms_hWltRS = NULL;

IDCardRead::IDCardRead()
: m_nDevicePort(0)
{
    //
}

IDCardRead::~IDCardRead()
{
    //
}

int IDCardRead::Initialize()
{
    int nReturn = -1;

    do 
    {
        ms_hSDTAPI = LoadLibraryW(L"sdtapi.dll");
        if (ms_hSDTAPI == NULL)
        {
            nReturn = -1;
            break;
        }

        ms_hWltRS = LoadLibraryW(L"WltRS.dll");
        if (ms_hWltRS == NULL)
        {
            nReturn = -2;
            break;
        }

        ms_fpSDT_OpenPort = (SDT_OpenPort)GetProcAddress(ms_hSDTAPI, "SDT_OpenPort");
        ms_fpSDT_ClosePort = (SDT_ClosePort)GetProcAddress(ms_hSDTAPI, "SDT_ClosePort");
        ms_fpSDT_StartFindIDCard = (SDT_StartFindIDCard)GetProcAddress(ms_hSDTAPI, "SDT_StartFindIDCard");
        ms_fpSDT_SelectIDCard = (SDT_SelectIDCard)GetProcAddress(ms_hSDTAPI, "SDT_SelectIDCard");
        ms_fpSDT_ReadBaseMsg = (SDT_ReadBaseMsg)GetProcAddress(ms_hSDTAPI, "SDT_ReadBaseMsg");

        if (
            (ms_fpSDT_OpenPort == NULL)
            || (ms_fpSDT_ClosePort == NULL)
            || (ms_fpSDT_StartFindIDCard == NULL)
            || (ms_fpSDT_SelectIDCard == NULL)
            || (ms_fpSDT_ReadBaseMsg == NULL)
            )
        {
            nReturn = -3;
            break;
        }

        ms_fpWLT_GetBmp = (WLT_GetBmp)GetProcAddress(ms_hWltRS, "GetBmp");
        if (ms_fpWLT_GetBmp == NULL)
        {
            nReturn = -4;
            break;
        }

        nReturn = 0;
    } while (false);

    if (nReturn != 0)
    {
        //clean
        ms_fpWLT_GetBmp = NULL;
        ms_fpSDT_OpenPort = NULL;
        ms_fpSDT_ClosePort = NULL;
        ms_fpSDT_StartFindIDCard = NULL;
        ms_fpSDT_SelectIDCard = NULL;
        ms_fpSDT_ReadBaseMsg = NULL;

        if (ms_hSDTAPI != NULL)
        {
            FreeLibrary(ms_hSDTAPI);
            ms_hSDTAPI = NULL;
        }

        if (ms_hWltRS != NULL)
        {
            FreeLibrary(ms_hWltRS);
            ms_hWltRS = NULL;
        }
    }

    return nReturn;
}

void IDCardRead::Uninitialize()
{
    ms_fpWLT_GetBmp = NULL;
    ms_fpSDT_OpenPort = NULL;
    ms_fpSDT_ClosePort = NULL;
    ms_fpSDT_StartFindIDCard = NULL;
    ms_fpSDT_SelectIDCard = NULL;
    ms_fpSDT_ReadBaseMsg = NULL;

    if (ms_hSDTAPI != NULL)
    {
        FreeLibrary(ms_hSDTAPI);
        ms_hSDTAPI = NULL;
    }

    if (ms_hWltRS != NULL)
    {
        FreeLibrary(ms_hWltRS);
        ms_hWltRS = NULL;
    }
}

int IDCardRead::ConnectDevice()
{
    int nReturn = -1;

    if (ms_fpSDT_OpenPort != NULL)
    {
        m_nDevicePort = 0;
        
        // detect from usb
        for (int nPort = 1001; nPort <= 1016; nPort ++)
        {
            if (ms_fpSDT_OpenPort(nPort) == 0x90)
            {
                m_nDevicePort = nPort;
                break;
            }
        }

        /* dll have bug. 
        if (m_nDevicePort == 0)
        {//dectect from usb failed, dectect from COM
            for (int nPort = 1; nPort <= 16; nPort ++)
            {
                if (ms_fpSDT_OpenPort(nPort) == 0x90)
                {
                    m_nDevicePort = nPort;
                    break;
                }
            }
        }
        */

        if (m_nDevicePort != 0)
        {
            nReturn = 0;
        }
        else
        {
            nReturn = -2;
        }
    }
    else
    {
        nReturn = -1;
    }

    return nReturn;
}

int IDCardRead::DisconnectDevice()
{
    int nReturn = -1;

    if (ms_fpSDT_ClosePort != NULL)
    {
        if (m_nDevicePort != 0)
        {
            if (ms_fpSDT_ClosePort(m_nDevicePort) == 0x90)
            {
                nReturn = 0;
            }
            else
            {
                nReturn = -2;
            }
            m_nDevicePort = 0;
        }
        else
        {
            nReturn = -2;
        }
    }
    else
    {
        nReturn = -1;
    }

    return nReturn;
}

int IDCardRead::DetectCard()
{
    int nReturn = -1;

    if (
        (ms_fpSDT_StartFindIDCard != NULL)
        && (ms_fpSDT_SelectIDCard != NULL)
        )
    {
        if (m_nDevicePort != 0)
        {
            unsigned char szRAPDU[4];
            if (ms_fpSDT_StartFindIDCard(m_nDevicePort, szRAPDU, 0) == 0x9F)
            {
                unsigned char szRAPDUSelect[8];
                if (ms_fpSDT_SelectIDCard(m_nDevicePort, szRAPDUSelect, 0) == 0x90)
                {
                    nReturn = 0;
                }
                else
                {
                    nReturn = -3;
                }
            }
            else
            {
                nReturn = -2;
            }
        }
        else
        {
            nReturn = -4;
        }
    }
    else
    {
        nReturn = -1;
    }

    return nReturn;
}

void IDCardRead::TrimRight(wchar_t *sInput)
{
    if (sInput != NULL)
    {
        int nEnd = wcslen(sInput) - 1;
        while (nEnd > 0)
        {
            if (sInput[nEnd] == L' ')
            {
                sInput[nEnd] = L'\0';
                nEnd --;
            }
            else
            {
                break;
            }
        }
    }
}

void IDCardRead::GetNationFromCode(wchar_t *sNation, int nNationCode)
{
    switch (nNationCode)
    {
    case 1:
        wcscpy(sNation, L"漢");
        break;
    case 2:
        wcscpy(sNation, L"蒙古");
        break;
    case 3:
        wcscpy(sNation, L"回");
        break;
    case 4:
        wcscpy(sNation, L"藏");
        break;
    case 5:
        wcscpy(sNation, L"維吾爾");
        break;
    case 6:
        wcscpy(sNation, L"苗");
        break;
    case 7:
        wcscpy(sNation, L"彝");
        break;
    case 8:
        wcscpy(sNation, L"壯");
        break;
    case 9:
        wcscpy(sNation, L"布依");
        break;
    case 10:
        wcscpy(sNation, L"朝鮮");
        break;
    case 11:
        wcscpy(sNation, L"滿");
        break;
    case 12:
        wcscpy(sNation, L"侗");
        break;
    case 13:
        wcscpy(sNation, L"瑤");
        break;
    case 14:
        wcscpy(sNation, L"白");
        break;
    case 15:
        wcscpy(sNation, L"土家");
        break;
    case 16:
        wcscpy(sNation, L"哈尼");
        break;
    case 17:
        wcscpy(sNation, L"哈薩克");
        break;
    case 18:
        wcscpy(sNation, L"傣");
        break;
    case 19:
        wcscpy(sNation, L"黎");
        break;
    case 20:
        wcscpy(sNation, L"傈僳");
        break;
    case 21:
        wcscpy(sNation, L"佤");
        break;
    case 22:
        wcscpy(sNation, L"畲");
        break;
    case 23:
        wcscpy(sNation, L"高山");
        break;
    case 24:
        wcscpy(sNation, L"拉祜");
        break;
    case 25:
        wcscpy(sNation, L"水");
        break;
    case 26:
        wcscpy(sNation, L"東鄉");
        break;
    case 27:
        wcscpy(sNation, L"納西");
        break;
    case 28:
        wcscpy(sNation, L"景頗");
        break;
    case 29:
        wcscpy(sNation, L"柯爾克孜");
        break;
    case 30:
        wcscpy(sNation, L"土");
        break;
    case 31:
        wcscpy(sNation, L"達斡爾");
        break;
    case 32:
        wcscpy(sNation, L"仫佬");
        break;
    case 33:
        wcscpy(sNation, L"羌");
        break;
    case 34:
        wcscpy(sNation, L"布朗");
        break;
    case 35:
        wcscpy(sNation, L"撒拉");
        break;
    case 36:
        wcscpy(sNation, L"毛南");
        break;
    case 37:
        wcscpy(sNation, L"仡佬");
        break;
    case 38:
        wcscpy(sNation, L"錫伯");
        break;
    case 39:
        wcscpy(sNation, L"阿昌");
        break;
    case 40:
        wcscpy(sNation, L"普米");
        break;
    case 41:
        wcscpy(sNation, L"塔吉克");
        break;
    case 42:
        wcscpy(sNation, L"怒");
        break;
    case 43:
        wcscpy(sNation, L"烏孜別克");
        break;
    case 44:
        wcscpy(sNation, L"俄羅斯");
        break;
    case 45:
        wcscpy(sNation, L"鄂溫克");
        break;
    case 46:
        wcscpy(sNation, L"德昂");
        break;
    case 47:
        wcscpy(sNation, L"保安");
        break;
    case 48:
        wcscpy(sNation, L"裕固");
        break;
    case 49:
        wcscpy(sNation, L"京");
        break;
    case 50:
        wcscpy(sNation, L"塔塔爾");
        break;
    case 51:
        wcscpy(sNation, L"獨龍");
        break;
    case 52:
        wcscpy(sNation, L"鄂倫春");
        break;
    case 53:
        wcscpy(sNation, L"赫哲");
        break;
    case 54:
        wcscpy(sNation, L"門巴");
        break;
    case 55:
        wcscpy(sNation, L"珞巴");
        break;
    case 56:
        wcscpy(sNation, L"基諾");
        break;
    case 97:
        wcscpy(sNation, L"其他");
        break;
    case 98:
        wcscpy(sNation, L"外國血統中國籍人士");
        break;
    default:
        wcscpy(sNation, L"");
        break;
    }
}

int IDCardRead::GetCardInformation(ID_CARD_INFORMATION *pInfo)
{
    int nReturn = -1;

    if (
        (ms_fpSDT_ReadBaseMsg != NULL)
        && (ms_fpWLT_GetBmp != NULL)
        )
    {
        if (pInfo != NULL)
        {
            if (m_nDevicePort != 0)
            {
                unsigned char szCHMsg[512];
                unsigned char szPHMsg[1024];
                unsigned int nCHMsg = 512;
                unsigned int nPHMsg = 1024;
                if (ms_fpSDT_ReadBaseMsg(m_nDevicePort, szCHMsg, &nCHMsg, szPHMsg, &nPHMsg, 0) == 0x90)
                {
                    memset(pInfo, 0, sizeof(ID_CARD_INFORMATION));
                    //name
                    memcpy(pInfo->szName, szCHMsg, 30);
                    TrimRight(pInfo->szName);
                    //gender
                    memcpy(pInfo->szGender, szCHMsg+30, 2);
                    TrimRight(pInfo->szGender);
                    if (wcscmp(pInfo->szGender, L"1") == 0)
                    {
                        wcscpy(pInfo->szGender, L"男");
                    }
                    else
                    {
                        wcscpy(pInfo->szGender, L"女");
                    }
                    //nation
                    memcpy(pInfo->szNation, szCHMsg+32, 4);
                    TrimRight(pInfo->szNation);
                    GetNationFromCode(pInfo->szNation, _wtoi(pInfo->szNation));
                    //birth
                    memcpy(pInfo->szBirth, szCHMsg+36, 16);
                    TrimRight(pInfo->szBirth);
                    //address
                    memcpy(pInfo->szAddress, szCHMsg+52, 70);
                    TrimRight(pInfo->szAddress);
                    //idcode
                    memcpy(pInfo->szIDCode, szCHMsg+122, 36);
                    TrimRight(pInfo->szIDCode);
                    //authority
                    memcpy(pInfo->szAuthority, szCHMsg+158, 30);
                    TrimRight(pInfo->szAuthority);
                    //issue day
                    memcpy(pInfo->szIssueDay, szCHMsg+188, 16);
                    TrimRight(pInfo->szIssueDay);
                    //expiry day
                    memcpy(pInfo->szExpiryDay, szCHMsg+204, 16);
                    TrimRight(pInfo->szExpiryDay);

                    //photo path
                    FILE *hFile = fopen("C:\\sfzhead.wlt", "w+b");
                    if (hFile != NULL)
                    {
                        fwrite(szPHMsg, 1, nPHMsg, hFile);
                        fclose(hFile);
                    }
                    ms_fpWLT_GetBmp("C:\\sfzhead.wlt", 2);
                    wcscpy(pInfo->szPhotoPath, L"C:\\sfzhead.bmp");
                    nReturn = 0;
                }
                else
                {
                    nReturn = -4;
                }
            }
            else
            {
                nReturn = -3;
            }
        }
        else
        {
            nReturn = -2;
        }
    }
    else
    {
        nReturn = -1;
    }

    return nReturn;
}


關注點:

1、定義函式指標方法。

如typedef int (WINAPI *SDT_OpenPort)(int nPort);

2、定義static函式指標變數。

如static SDT_OpenPort             ms_fpSDT_OpenPort;

3、靜態的初始,反初始函式。

    static int Initialize();
    static void Uninitialize();