Windowsの下でDllダイナミックライブラリと呼び出しを作成する

13204 ワード

  • DLL:Dynamic Link Library、すなわち、複数のプログラムで同時に使用できるコードとデータを含む動的リンクライブラリの概要.これはmicrosoftがwindowsオペレーティングシステムで共有関数ライブラリの概念を実現する実現方法である.
  • 方法1、新規工事:VS 2015を開き、新規プロジェクトを選択し、クリックします:VisualC+->Win 32->Win 32プロジェクト(名前、パスを記入)->OK->次へ(アプリケーションタイプ選択Dll、空のプロジェクトをチェック)->完了これでDllエンジニアリング2が作成され、コードが空のプロジェクトに.hファイルと.cppファイルが追加され、それぞれ:
  • /*
    FileName: MyDll.h  
    Author:Leon Dang   
    Date:2017.05.09
    Description:         
    */
    
    #pragma once
    
    #ifdef MYDLLTEST_EXPORTS
    #define MYDLLTEST_API __declspec(dllexport)
    #else
    #define MYDLLTEST_API __declspec(dllimport)
    #endif
    
    #include 
    #include 
    
    MYDLLTEST_API int Add(int x, int y, int z);
    
    MYDLLTEST_API int Display(std::string );
    
    /*
    FileName: MyDll.cpp  
    Author:Leon Dang   
    Date:2017.05.09
    Description:            
    */
    
    #include "MyDll.h"
    
    int Add(int x, int y, int z)
    {
        return (x + y + z);
    }
    
    int Display(std::string str)
    {
        std::cout << str << std::endl;
        return 0;
    }
    

    3、ライブラリファイルを生成する上記コードをコンパイルした後、エンジニアリングDebugディレクトリの下で相応のものを生成する.libファイルと.dllファイル.私の工事経路の下でMyDllを生産しました.libとMyDlldll. * これで、ダイナミックライブラリの作成が完了しました.次に、これらのダイナミックライブラリの使用方法を見てみましょう.
  • ダイナミックライブラリ使用方法(一)、ダイナミックライブラリのダイナミック静的呼び出し方法
  • 1、新しいテストダイナミックライブラリプロジェクト上記の最初のステップの新しいプロジェクトのように、今回はMyDllTestというダイアログボックスのあるMFCプロジェクトを新規作成し、ダイアログボックスにButtonボタンを新規作成してダイナミックライブラリの関数をテストします.2、新規ライブラリフォルダ工事と同じ経路でlibフォルダを新規作成し、libライブラリ、MyDll.libとMyDllhこの経路の下に入れる.3、配置ライブラリパス右クリック工事名、選択属性、顺次配置:(1)、C/C++通常をクリックして、ディレクトリを添付します:さっきのlibパスを入れて、他のパスがあれば、セミコロンで分割することに注意します;(2)、コネクタの通常をクリックして、ライブラリのディレクトリを添付して、同じくさっきのlibパスを入れて、もし他のパスがあれば、セミコロンで分割することに注意します;(3)、MyDll.dllファイルを:C:WindowsSysWOW 64(64ビット)、またはC:WindowsSystem 32(32ビット)に挿入します.これでライブラリパスの構成が整いました.4、ダイナミックライブラリ関数を呼び出します.MFCダイアログボックスにButtonを新規作成し、このButtonの応答関数に入ります.コードにライブラリファイルをロードし、この関数を使用します.以下のようにします.
    /*
    FileName: MyDllTest.h 
    Author:Leon Dang   
    Date:2017.05.09
    Description:        
    */
    
    
    // MyDllTestDlg.h :    
    //
    
    #pragma once
    
    
    // MyDllTestDlg    
    class MyDllTestDlg : public CDialogEx
    {
    //   
    public:
        MyDllTestDlg(CWnd* pParent = NULL); //       
    
    //      
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_MYDLLTEST_DIALOG };
    #endif
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV   
    
    
    //   
    protected:
        HICON m_hIcon;
    
        //          
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP()
    public:
        afx_msg void OnBnClickedButton(); //Button       
    };
    
    
    
    /*
    FileName: MyDllTest.cpp 
    Author:Leon Dang   
    Date:2017.05.09
    Description:        
    */
    
    
    // MyDllTestDlg.cpp :     
    //
    
    #include "stdafx.h"
    #include MyDllTest.h"
    #include "MyDllTestDlg.h"
    #include "afxdialogex.h"
    #include "MyDll.h"       //        
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    #pragma comment(lib,"MyDll.lib")   //  lib 
    
    //       “  ”     CAboutDlg    
    
    class CAboutDlg : public CDialogEx
    {
    public:
        CAboutDlg();
    
    //      
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_ABOUTBOX };
    #endif
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV   
    
    //   
    protected:
        DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
    END_MESSAGE_MAP()
    
    
    // CMyDllTestDlg   
    
    
    
    CMyDllTestDlg::CMyDllTestDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(IDD_MYDLLTEST_DIALOG, pParent)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CMyDllTestDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CMyDllTestDlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BUTTON, &CMyDllTestDlg::OnBnClickedButton)
    END_MESSAGE_MAP()
    
    
    // CMyDllTestDlg       
    
    BOOL MyDllTestDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        //  “  ...”           。
    
        // IDM_ABOUTBOX           。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            BOOL bNameValid;
            CString strAboutMenu;
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
            ASSERT(bNameValid);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        //          。                ,     
        //       
        SetIcon(m_hIcon, TRUE);         //      
        SetIcon(m_hIcon, FALSE);        //      
    
        // TODO:             
    
        return TRUE;  //           ,     TRUE
    }
    
    void CMyDllTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else
        {
            CDialogEx::OnSysCommand(nID, lParam);
        }
    }
    
    //              ,        
    //        。        /      MFC     ,
    //           。
    
    void CMyDllTestDlg::OnPaint()
    {
        if (IsIconic())
        {
            CPaintDC dc(this); //           
    
            SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
    
            //             
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;
    
            //     
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialogEx::OnPaint();
        }
    }
    
    //                      
    //  。
    HCURSOR CMyDllTestDlg::OnQueryDragIcon()
    {
        return static_cast(m_hIcon);
    }
    
    
    //         Add    Display  
    void CMyDllTestDlg::OnBnClickedButton()
    {
        int num = Add(2, 3, 4);
        Display("MyDll Test");
        TRACE("This is a Dll Test
    "
    ); }

    (二)、動的ライブラリの動的呼び出し方法動的ライブラリの動的呼び出し方法はLoadLibrary関数でロードする必要があり、ロードが完了したら中の関数を使用することができる.1、フォルダを作成して.dllファイルを保存するか、直接この動的ライブラリファイルと実行可能ファイルを一つのディレクトリの下に保存する.2、コードに表示される動的ライブラリをロードして、ダイナミックライブラリの関数を使用します.
    typedef void (*MYFUNCTION)(void);  
    HINSTANCE hInstance;  
    MYFUNCTION func;  
    hInstance = ::LoadLibrary("dllname.dll"); //dll               
    func = (MYFUNCTION)GetProcAddress(hInstance, "FunctionName");  //         
    (*func)();  //      
    ::FreeLibrary();  

    このメソッドは、関数アドレスを取得するときに取得できない可能性があります.空のポインタを取得します.解決策は、動的ライブラリソースファイルで関数を宣言するには、次のようにします.
    #pragma once
    
    #ifdef MYDLLTEST_EXPORTS
    #define MYDLLTEST_API __declspec(dllexport)
    #else
    #define MYDLLTEST_API __declspec(dllimport)
    #endif
    
    #include 
    #include 
    
    extern "c" MYDLLTEST_API int Add(int x, int y, int z);
    
    extern "c" MYDLLTEST_API int Display(std::string );
    
  • まとめ:これで、新しいダイナミックライブラリからダイナミックライブラリへのダイナミックライブラリの具体的な呼び出しをまとめ、後で確認するために使用します.