• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            VC++動(dòng)態(tài)鏈接庫(kù)編程之DLL典型實(shí)例

            動(dòng)態(tài)鏈接庫(kù)DLL實(shí)現(xiàn)了庫(kù)的共享,體現(xiàn)了代碼重用的思想。我們可以把廣泛的、具有共性的、能夠多次被利用的函數(shù)和類定義在庫(kù)中。這樣,在再次使用這些函數(shù)和類的時(shí)候,就不再需要重新添加與這些函數(shù)和類相關(guān)的代碼。具有共性的問(wèn)題大致有哪些呢?筆者歸納如下:

              (1)通用的算法

              圖像處理、視頻音頻解碼、壓縮與解壓縮、加密與解密通常采用某些特定的算法,這些算法較固定且在這類程序中往往經(jīng)常被使用。

              (2)純資源DLL

              我們可以從DLL中獲取資源,對(duì)于一個(gè)支持多種語(yǔ)言的應(yīng)用程序而言,我們可以判斷操作系統(tǒng)的語(yǔ)言,并自動(dòng)為應(yīng)用程序加載與OS對(duì)應(yīng)的語(yǔ)言。這是多語(yǔ)言支持應(yīng)用程序的一般做法。

              (3)通信控制DLL

              串口、網(wǎng)口的通信控制函數(shù)如果由DLL提供則可以使應(yīng)用程序輕松不少。在工業(yè)控制、modem程序甚至socket通信中,經(jīng)常使用通信控制DLL。

              本節(jié)將給出DLL的三個(gè)典型應(yīng)用實(shí)例。

              7.1 算法DLL

              我們直接用讀者的一個(gè)提問(wèn)作為例子。

              宋寶華先生,您好!

              我在dev.yesky.com上看到你連載的《VC++動(dòng)態(tài)鏈接庫(kù)編程》,覺(jué)得非常好。我以前主要是用Delphi的,C/C++學(xué)過(guò),對(duì)Win32和VCL比較熟悉,但是沒(méi)有接觸過(guò)VC++,對(duì)MFC很陌生。這段時(shí)間和一個(gè)同學(xué)合作做光學(xué)成像的計(jì)算機(jī)模擬,用到傅立葉變換,手里面有例程是VC++寫(xiě)的。我們的界面是用Delphi開(kāi)發(fā),需要將其傅立葉變換功能提出做一個(gè)DLL供Delphi調(diào)用。苦于不懂MFC,試了很多方法,都不成功,最后只得采用折衷方案,簡(jiǎn)單修改一下程序,傳一個(gè)參數(shù)進(jìn)去,當(dāng)作exe來(lái)調(diào)用,才沒(méi)有耽擱后續(xù)進(jìn)程。

              ……

              謝謝!

                    致

              禮!

                     某某

              學(xué)習(xí)過(guò)較高級(jí)別數(shù)學(xué)(概率統(tǒng)計(jì)與隨機(jī)過(guò)程)、信號(hào)與線性系統(tǒng)及數(shù)字信號(hào)處理的讀者應(yīng)該知道,傅立葉變換是一種在信號(hào)分析中常用的算法,用于時(shí)域和頻域的相互轉(zhuǎn)換。FFT變換算法通用而有共性,我們適宜把它集成在一個(gè)DLL中。

              隨后,這位讀者提供了這樣的一個(gè)函數(shù):

            /* 函數(shù)名稱:FFT()
            * 參數(shù):
            * complex<double> * TD - 指向時(shí)域數(shù)組的指針
            * complex<double> * FD - 指向頻域數(shù)組的指針
            * r -2的冪數(shù),即迭代次數(shù)
            * 返回值: 無(wú)。
            * 說(shuō)明:該函數(shù)用來(lái)實(shí)現(xiàn)快速傅立葉變換
            */

            void FFT(complex<double> * TD, complex<double> * FD, int r)
            {
             LONG count; // 傅立葉變換點(diǎn)數(shù)
             int i,j,k; // 循環(huán)變量
             int bfsize,p; // 中間變量
             double angle; // 角度
             complex<double> *W,*X1,*X2,*X;
             count = 1 << r; //傅立葉變換點(diǎn)數(shù)

             // 分配運(yùn)算所需存儲(chǔ)器

             W = new complex<double>[count / 2];
             X1 = new complex<double>[count];
             X2 = new complex<double>[count];

             // 計(jì)算加權(quán)系數(shù)

             for(i = 0; i < count / 2; i++)
             {
              angle = -i * PI * 2 / count;
              W[i] = complex<double> (cos(angle), sin(angle));
             }

             // 將時(shí)域點(diǎn)寫(xiě)入X1

             memcpy(X1, TD, sizeof(complex<double>) * count);

             // 采用蝶形算法進(jìn)行快速傅立葉變換

             for(k = 0; k < r; k++)
             {
              for(j = 0; j < 1 << k; j++)
              {
               bfsize = 1 << (r-k);
               for(i = 0; i < bfsize / 2; i++)
               {
                p = j * bfsize;
                X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2];
                X2[i + p + bfsize / 2] = (X1[i + p] - X1[i + p + bfsize / 2]) * W[i * (1<<k)];
               }
              }
              X = X1;
              X1 = X2;
              X2 = X;
             }

             // 重新排序

             for(j = 0; j < count; j++)
             {
              p = 0;
              for(i = 0; i < r; i++)
              {
               if (j&(1<<i))
               {
                p+=1<<(r-i-1);
               }
              }
              FD[j]=X1[p];
             }

             // 釋放內(nèi)存

             delete W;
             delete X1;
             delete X2;
            }

              既然有了FFT這個(gè)函數(shù),我們要把它做在DLL中,作為DLL的一個(gè)接口將是十分簡(jiǎn)單的,其步驟如下:

              (1)利用MFC向?qū)Ы⒁粋€(gè)非MFC DLL;

              (2)在工程中添加fft.h和fft.cpp兩個(gè)文件;

              fft.h的源代碼為:

            #ifndef FFT_H
            #define FFT_H

            #include <complex>

            using namespace std;
            extern "C" void __declspec(dllexport) __stdcall FFT(complex<double> * TD, complex<double> * FD, int r);

            #define PI 3.1415926
            #endif

            fft.cpp的源代碼為:

            /* 文件名:fft.cpp */

            #include "fft.h"
            void __stdcall FFT(complex<double> * TD, complex<double> * FD, int r)
            {
             …//讀者提供的函數(shù)代碼
            }

              在任何編程語(yǔ)言中使用Win32 API LoadLibrary都可以加載這個(gè)DLL,而使用GetProcAddress(hDll, "FFT")則可以獲得函數(shù)FFT的地址,讀者所提到的Delphi當(dāng)然也不例外。

              這個(gè)DLL中有兩點(diǎn)需要注意:

              (1)使用extern "C"修飾函數(shù)聲明,否則,生成的DLL只能供C++調(diào)用;

              (2)使用__stdcall修飾函數(shù)聲明及定義,__stdcall是Windows API的函數(shù)調(diào)用方式。
            7.2純資源DLL

              我們?cè)趹?yīng)用程序中產(chǎn)生如圖18所示的資源(對(duì)話框),單擊此處下載本工程


            圖18 中文對(duì)話框

              在與這個(gè)應(yīng)用程序相同的工作區(qū)里利用MFC向?qū)Ы蓚€(gè)簡(jiǎn)單的DLL,把應(yīng)用工程中的資源全選后分別拷貝到ChineseDll和EngLishDll,在EnglishDll工程的資源文件中搜索下面的語(yǔ)句:

            /////////////////////////////////////////////////////////////////////////////

            // Chinese (P.R.C.) resources

            #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
            #ifdef _WIN32
            LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
            #pragma code_page(936)
            #endif //_WIN32

              將其改為:

            /////////////////////////////////////////////////////////////////////////////
            // English (U.S.) resources

            #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
            #ifdef _WIN32

            LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

            #pragma code_page(1252)
            #endif //_WIN32

              并將其中所有的中文翻譯為英文。這個(gè)DLL為我們提供了如圖19所示的對(duì)話框資源。


            圖19英文對(duì)話框

              修改應(yīng)用工程的InitInstance()函數(shù),在

            CResourceDllCallDlg dlg;
            m_pMainWnd = &dlg;
            int nResponse = dlg.DoModal();

              之前(即對(duì)話框顯示之前)添加如下代碼:

            //獲取操作系統(tǒng)的語(yǔ)言

            WORD wLangPID = PRIMARYLANGID( GetSystemDefaultLangID() );
            if( LANG_CHINESE == wLangPID )
            {
             hLanguageDll = LoadLibrary( "ChineseDll.dll" ); //加載中文資源
            }
            else
            {
             hLanguageDll = LoadLibrary( "EnglishDll.dll" ); //加載英文資源
            }

            if( NULL == hLanguageDll )
            {
             AfxMessageBox( "Load DLL failure" );
             return FALSE;
            }
            AfxSetResourceHandle( hLanguageDll ); //設(shè)置當(dāng)前的資源句柄

              這樣的應(yīng)用程序?qū)⒕哂凶赃m應(yīng)性質(zhì),在中文OS中顯示中文資源,在英文OS中則顯示英文資源。
            7.3通信控制DLL

              我們?cè)谶@里舉一個(gè)串口通信類的例子。

              也許您需要了解一點(diǎn)串口通信的背景知識(shí),其實(shí)串口到處都看得到,譬如PC機(jī)的COM口即為串行通訊口(簡(jiǎn)稱串口)。如圖20,打開(kāi)Windows的設(shè)備管理器,我們看到了COM口。

              在Windows系統(tǒng),需通過(guò)DCB(Device Control Block)對(duì)串口進(jìn)行配置。利用Windows API GetCommState函數(shù)可以獲取串口當(dāng)前配置;利用SetCommState函數(shù)則可以設(shè)置串口通訊的參數(shù)。

              串行通信通常按以下四步進(jìn)行:

              (1)打開(kāi)串口;

              (2)配置串口;

              (3)數(shù)據(jù)傳送;

              (4)關(guān)閉串口。


            圖20 PC的串口

              由此可見(jiàn),我們需要給串口控制DLL提供如下四個(gè)接口函數(shù):

            //打開(kāi)指定的串口,其參數(shù)port為端口號(hào)

            BOOL ComOpen(int port); //在這個(gè)函數(shù)里使用默認(rèn)的參數(shù)設(shè)置串口

            //將打開(kāi)的串口關(guān)閉

            void ComClose(int port);

            //將串口接收緩沖區(qū)中的數(shù)據(jù)放到buffer中

            int GetComData(char *buf, int buf_len);

            //將指定長(zhǎng)度的數(shù)據(jù)發(fā)送到串口

            int SendDataToCom(LPBYTE buf,int buf_Len);

              下面給出了DLL接口的主要源代碼框架:

            //com.h:com類通信接口

            class AFX_EXT_CLASS com
            {
             public:
              ComOpen(int port)
              {
               …
              }
              int SendDataToCom(LPBYTE buf,int buf_Len)
              {
               …
              }
              int GetComData(char *buf, int buf_len)
              {
               …
              }
              void ComClose()
              {
               …
              }
             }

              我們編寫(xiě)一控制臺(tái)程序來(lái)演示DLL的調(diào)用:

            #include <iostream>
            #include <exception>

            using namespace std;

            #include <windows.h>
            #include "com.h" //包含DLL中導(dǎo)出類的頭文件 int main(int argc, char *argv[])
            {
             try
             {
              char str[] = "com_class test";
              com com1;
              com1.ComOpen (1);
              for(int i=0; i<100; i++) //以同步方式寫(xiě)com的buffer
              {
               Sleep(500);
               com1.SendDataToCom (str,strlen(str));
              }
              com1.ComClose ();
             }
             catch(exception &e)
             {
              cout << e.what() << endl;
             }
             return 0;
            }

              DLL的編寫(xiě)與調(diào)用方法及主要應(yīng)用皆已講完,在下一節(jié)里,我們將看到比較“高深”的主題――DLL木馬。曾幾何時(shí),DLL木馬成為了病毒的一種十分重要的形式,是DLL的什么特性使得它能夠成為一種病毒?下一節(jié)我們將揭曉謎底。

            posted on 2009-06-09 21:20 wrh 閱讀(303) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            導(dǎo)航

            <2012年3月>
            26272829123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統(tǒng)計(jì)

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            狠狠色婷婷综合天天久久丁香| 国产福利电影一区二区三区久久老子无码午夜伦不 | 韩国三级中文字幕hd久久精品 | 久久国产福利免费| 精品久久777| 97久久精品无码一区二区| 久久天天躁狠狠躁夜夜avapp| 性做久久久久久久久浪潮| 亚洲AV伊人久久青青草原| 国产精品免费久久久久久久久| 91亚洲国产成人久久精品| 狠狠人妻久久久久久综合蜜桃| 91精品婷婷国产综合久久| 99热精品久久只有精品| 久久WWW免费人成—看片| 人人狠狠综合久久亚洲| 久久精品卫校国产小美女| 亚洲va国产va天堂va久久| 国产成人精品免费久久久久| 久久精品国产精品亚洲精品| 久久国产美女免费观看精品| 久久综合精品国产一区二区三区| 日产精品久久久久久久| 久久免费的精品国产V∧| 亚洲国产天堂久久综合网站| 欧美亚洲日本久久精品| 久久国产色av免费看| 97精品国产91久久久久久| 精品国产综合区久久久久久| 久久人人爽人人爽人人片av麻烦| 午夜不卡久久精品无码免费| 久久精品成人国产午夜| 久久午夜免费视频| 国产精品久久自在自线观看| 少妇被又大又粗又爽毛片久久黑人| 国内精品久久久久影院亚洲| 97久久精品午夜一区二区| 日产精品久久久久久久| 99久久婷婷国产综合精品草原 | 久久人爽人人爽人人片AV| 国产农村妇女毛片精品久久|