• <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>

            Codejie's C++ Space

            Using C++

            練習(xí):LoadLibrary調(diào)用DLL中的Class

                使用LoadLibrary函數(shù)調(diào)用DLL中的函數(shù)的方法一般被稱為“顯式”調(diào)用,意義和使用lib的“隱式”調(diào)用相對(duì)應(yīng)。
                LoadLibrary調(diào)用DLL中的函數(shù)的方法比較簡(jiǎn)單,通過(guò)GetProcAddress獲得函數(shù)的在DLL的地址就可以訪問(wèn)了,但DLL中的Class訪問(wèn)就相對(duì)很復(fù)雜了(目前我就發(fā)現(xiàn)這一種顯式調(diào)用方式,哪位有其他方法么?)。一個(gè)簡(jiǎn)單的情況就是Class的函數(shù)在調(diào)用是,其名稱是什么?還有Class的contructor函數(shù)怎么調(diào)用?下面的代碼將演示下這些問(wèn)題。
            這里是DLL的文件:
                DllMain.h

             1#ifndef __DLLMAIN_H__
             2#define __DLLMAIN_H__
             3
             4#include <string>
             5
             6#define DllExport __declspec(dllexport)
             7
             8extern "C" int DllExport Func(int x);
             9
            10extern "C" class DllExport CA
            11{
            12public:
            13    CA(int x);
            14    ~CA();
            15
            16    int Func0();
            17    int Func(int x);
            18    const std::string& FuncS(int x, const std::string& str) const;
            19protected:
            20    int _x;
            21}
            ;
            22
            23
            24#endif

                DllMain.cpp
             1#include <iostream>
             2
             3#include "DllMain.h"
             4
             5int Func(int x)
             6{
             7    return x * 10;
             8}

             9
            10CA::CA(int x)
            11   : _x(x)
            12{
            13    std::cout << "contructor" << std::endl;
            14}

            15
            16CA::~CA()
            17{
            18    std::cout << "destructor" << std::endl;
            19}

            20
            21int CA::Func0()
            22{
            23    return _x;
            24}

            25
            26int CA::Func(int x)
            27{
            28    return _x * x;
            29}

            30
            31const std::string& CA::FuncS(int x, const std::string &str) const
            32{
            33    return str;
            34}

            35

                這里需要.def文件了,因?yàn)镃lass在DLL中的命名不像函數(shù)命名那么簡(jiǎn)單,會(huì)被轉(zhuǎn)義的,像CA::Func(int)在DLL的export表中就是?Func@CA@@QAEHH@Z,具體定義說(shuō)明可參看《xxx的自我修養(yǎng)》一書(shū)。因此,這里需要使用.def文件對(duì)函數(shù)進(jìn)行重命名,下面是DllMain.def文件內(nèi)容:
             
            1LIBRARY TESTDLL
            2EXPORTS
            3    Func = Func
            4    CA::CA(int= ??0CA@@QAE@H@Z
            5    CA::~CA = ??1CA@@QAE@XZ
            6    CA::Func0 = ?Func0@CA@@QAEHXZ
            7    CA::Func(int= ?Func@CA@@QAEHH@Z
            8    ;CA::FuncS(int,std::basic_string<char>&= ?FuncS@CA@@QBEABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HABV23@@Z
            9    CA::FuncS = ?FuncS@CA@@QBEABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HABV23@@Z


                多說(shuō)一句,這里.def的編寫很需要Depends(Dependency Walker)工具的支持,其是查看DLL的首選工具啊。。


                編譯DLL,用下面代碼進(jìn)行測(cè)試:
                LoadLib.cpp
             1#include <iostream>
             2#include <string>
             3
             4#include <windows.h>
             5
             6//#include "DllMain.h"
             7
             8#define DllExport __declspec(dllexport)
             9
            10extern "C" int DllExport Func(int x);
            11
            12extern "C" class DllExport CA
            13{
            14public:
            15    CA(int x);
            16    ~CA();
            17
            18    int Func0();
            19    int Func(int x);
            20    const std::string& FuncS(int x, const std::string& str) const;
            21
            22private:
            23    int _x;
            24}
            ;
            25
            26typedef int (*func)(int);
            27typedef void (WINAPI *PCTOR)(int);
            28typedef int (WINAPI *func0)(void);
            29typedef int (WINAPI *funcc)(int);
            30typedef const std::string& (WINAPI *funcs)(int,const std::string&);
            31typedef void (WINAPI *PDTOR)(void);
            32
            33int main()
            34{
            35    HINSTANCE hdll;
            36    hdll = LoadLibraryA(("../DLLTEST/Debug/DLLTEST.dll"));
            37    if(hdll != NULL)
            38    {
            39        func pf = (func)GetProcAddress(hdll, "Func");
            40        std::cout << pf(10<< std::endl;
            41        CA* a = (CA*)malloc(sizeof(CA));
            42        PCTOR pc = (PCTOR)GetProcAddress(hdll, "CA::CA(int)");
            43        _asm { MOV ECX, a } 
            44        pc(5);
            45        func0 pf0 = (func0)GetProcAddress(hdll, "CA::Func0");
            46        _asm {MOV ECX, a }
            47        std::cout << pf0() << std::endl;
            48        funcc pfc = (funcc)GetProcAddress(hdll, "CA::Func(int)");
            49        _asm { MOV ECX, a }
            50        std::cout << pfc(10<< std::endl;
            51        funcs pfs = (funcs)GetProcAddress(hdll, "CA::FuncS");
            52        _asm { MOV ECX, a }
            53        std::cout << pfs(0, std::string("hello world")) << std::endl;
            54        PDTOR pd = (PDTOR)GetProcAddress(hdll, "CA::~CA");
            55        _asm { MOV ECX, a } 
            56        pd();        
            57        free(a);    
            58    }

            59    FreeLibrary(hdll);
            60    
            61    return 0;
            62}


                結(jié)果還算正常:
            1100
            2contructor
            35
            450
            5hello world
            6destructor
            7


                上面的代碼基本演示了DLL中Class的簡(jiǎn)單使用,包括對(duì)contructor、destrunctor的調(diào)用,有參、無(wú)參、多參函數(shù)調(diào)用,不知道有啥缺陷,但至少Work了,嘿嘿~
                由上述代碼可以看出,這種“顯式”使用DLL中的Class是非常繁瑣和危險(xiǎn)的事情,因此我覺(jué)得能用“隱式”就不要用“顯式”,能靜態(tài)就不要用動(dòng)態(tài)。。。
                注意到?jīng)],代碼沒(méi)有演示繼承和虛函數(shù),那是因此我加入Virtual函數(shù),程序就會(huì)core,實(shí)在搞不定,這里也就沒(méi)法給出好的方案來(lái),不知道哪位有啥建議么。。。
                上面代碼參考了如下地址:
                      http://www.codeproject.com/dll/classesexportedusingLL.asp
                      http://blog.csdn.net/jdcb2001/archive/2006/11/21/1401569.aspx

            posted on 2009-09-24 17:50 codejie 閱讀(25492) 評(píng)論(8)  編輯 收藏 引用 所屬分類: C++

            評(píng)論

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class[未登錄](méi) 2009-09-25 01:17 Liu

            最近很高產(chǎn)么,看來(lái)在M記沒(méi)事可干阿

            繼續(xù)寫,我也學(xué)習(xí)學(xué)習(xí)  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2009-09-25 09:59 陳梓瀚(vczh)

            鑒于復(fù)雜參數(shù)的計(jì)算也有可能會(huì)毀掉ecx,而且你又不能再參數(shù)放進(jìn)去之后再修改ecx,所以你還是老老實(shí)實(shí)import一個(gè)完整的類吧……  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2009-09-25 11:43 codejie

            @Liu
            M記現(xiàn)在還沒(méi)有想起讓我做什么,我也是吃了空,想到啥就寫點(diǎn)啥,沒(méi)目的,估計(jì)也‘產(chǎn)’不出什么。。。別學(xué)了,省的耽誤了你老人家~
            另,我在看你A國(guó)的代碼,那叫一個(gè)慘啊,怎么也想不明白,號(hào)稱‘技術(shù)領(lǐng)先’的A國(guó)人,怎么會(huì)寫出這樣的代碼。。。  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2009-09-25 11:46 codejie

            @陳梓瀚(vczh)
            我也知道這種方式不好,至少virtual我還沒(méi)有搞定。你說(shuō)的使用import方式該如何做?能給給實(shí)例不?我現(xiàn)在想解決的問(wèn)題就是,如果只有DLL,沒(méi)有l(wèi)ib的情況下,如何使用‘顯式’方式訪問(wèn)DLL中的Class。  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2009-09-25 15:47 溪流

            @codejie

            只有 DLL(如果不知道函數(shù)名,即不給出 .def),同樣不能“顯式”調(diào)用 DLL 中的函數(shù),不是嗎?
            不過(guò)同樣可以用你上面的工具找出函數(shù)名稱,然后 GetProcAddress,然后使用……  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2009-09-25 17:10 codejie

            @溪流
            不知道exports函數(shù)名的情況下使用DLL是一種比較極端的情況,不光是函數(shù)名稱不知道,函數(shù)的參數(shù)更是一個(gè)問(wèn)題,.def中多數(shù)不說(shuō)明參數(shù)的。
            這里使用LoadLibrary的‘顯式’調(diào)用,一般應(yīng)該多數(shù)用于實(shí)時(shí)加載DLL,而不是程序啟動(dòng)就加載DLL,這樣作便于管理程序的內(nèi)存使用情況,記得在早期的windows16位機(jī)器上常用,還有就是利用DLL特性做plugins的程序中。
            這里的代碼只是我吃了空而突發(fā)奇想的,跟你說(shuō)的一樣,現(xiàn)實(shí)中應(yīng)該很少用的。  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2012-07-17 09:14 Richard Wei

            如果要用顯試調(diào)用類,建議還是用接口方式吧,導(dǎo)出一個(gè)CreateInstance(interface** ppInterface)就可以了,簡(jiǎn)單又方便,具體參考COM  回復(fù)  更多評(píng)論   

            # re: 練習(xí):LoadLibrary調(diào)用DLL中的Class 2012-07-17 09:43 codejie

            @Richard Wei
            神奇的COM, 龐大的COM, 恐怖的COM。。。  回復(fù)  更多評(píng)論   

            公告

            Using C++

            導(dǎo)航

            統(tǒng)計(jì)

            留言簿(73)

            隨筆分類(513)

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国产精品美女久久久| 亚洲欧美精品伊人久久| 久久er国产精品免费观看8| 久久久婷婷五月亚洲97号色| 久久精品国产久精国产一老狼| 久久这里只精品国产99热| 久久久久AV综合网成人| 久久发布国产伦子伦精品| 久久av无码专区亚洲av桃花岛| 久久精品国产亚洲AV大全| 久久电影网一区| 国产综合免费精品久久久| 久久久久久极精品久久久| 国产精品久久久久久久人人看 | 久久国产精品免费一区二区三区| 久久国产亚洲精品麻豆| 久久人妻少妇嫩草AV蜜桃| 精品无码久久久久国产动漫3d| 亚洲国产美女精品久久久久∴| 国产精品99久久99久久久| 精品综合久久久久久88小说| 久久成人小视频| 国产精品久久久久…| 看全色黄大色大片免费久久久| 欧美亚洲国产精品久久高清| 国内精品久久久久伊人av| 国产三级精品久久| 国产色综合久久无码有码| 成人久久综合网| 久久精品国产99久久久古代 | 99久久99这里只有免费的精品| 国产精品va久久久久久久| 精品久久人人爽天天玩人人妻| 久久午夜电影网| 精品久久久中文字幕人妻| 91久久九九无码成人网站| 久久久一本精品99久久精品88| 亚洲国产二区三区久久| 久久人人妻人人爽人人爽| 无码国内精品久久综合88 | 精品久久香蕉国产线看观看亚洲|