【转载】LoadLibrary调用DLL中的Class

时间:2021-03-09 08:44:37

    【转自】http://www.cppblog.com/codejie/archive/2009/09/24/97141.html

    使用LoadLibrary函数调用DLL中的函数的方法一般被称为“显式”调用,意义和使用lib的“隐式”调用相对应。 

    LoadLibrary调用DLL中的函数的方法比较简单,通过GetProcAddress获得函数的在DLL的地址就可以访问了,但DLL中的Class访问就相对很复杂了(目前我就发现这一种显式调用方式,哪位有其他方法么?)。一个简单的情况就是Class的函数在调用是,其名称是什么?还有Class的contructor函数怎么调用?下面的代码将演示下这些问题。 
这里是DLL的文件: 
    DllMain.h 

 1 【转载】LoadLibrary调用DLL中的Class#ifndef __DLLMAIN_H__
 2 【转载】LoadLibrary调用DLL中的Class #define  __DLLMAIN_H__
 3 【转载】LoadLibrary调用DLL中的Class
 4 【转载】LoadLibrary调用DLL中的Class #include  < string >
 5 【转载】LoadLibrary调用DLL中的Class
 6 【转载】LoadLibrary调用DLL中的Class #define  DllExport __declspec(dllexport)
 7 【转载】LoadLibrary调用DLL中的Class
 8 【转载】LoadLibrary调用DLL中的Class extern   " C "   int  DllExport Func( int  x);
 9 【转载】LoadLibrary调用DLL中的Class
10 【转载】LoadLibrary调用DLL中的Class extern   " C "   class  DllExport CA
11 【转载】LoadLibrary调用DLL中的Class {
12【转载】LoadLibrary调用DLL中的Classpublic:
13【转载】LoadLibrary调用DLL中的Class    CA(int x);
14【转载】LoadLibrary调用DLL中的Class    ~CA();
15【转载】LoadLibrary调用DLL中的Class
16【转载】LoadLibrary调用DLL中的Class    int Func0();
17【转载】LoadLibrary调用DLL中的Class    int Func(int x);
18【转载】LoadLibrary调用DLL中的Class    const std::string& FuncS(int x, const std::string& str) const;
19【转载】LoadLibrary调用DLL中的Classprotected:
20【转载】LoadLibrary调用DLL中的Class    int _x;
21【转载】LoadLibrary调用DLL中的Class}
;
22 【转载】LoadLibrary调用DLL中的Class
23 【转载】LoadLibrary调用DLL中的Class
24 【转载】LoadLibrary调用DLL中的Class #endif

    DllMain.cpp 
 1 【转载】LoadLibrary调用DLL中的Class#include  < iostream >
 2 【转载】LoadLibrary调用DLL中的Class
 3 【转载】LoadLibrary调用DLL中的Class #include  " DllMain.h "
 4 【转载】LoadLibrary调用DLL中的Class
 5 【转载】LoadLibrary调用DLL中的Class int  Func( int  x)
 6 【转载】LoadLibrary调用DLL中的Class {
 7【转载】LoadLibrary调用DLL中的Class    return x * 10;
 8【转载】LoadLibrary调用DLL中的Class}

 9 【转载】LoadLibrary调用DLL中的Class
10 【转载】LoadLibrary调用DLL中的Class CA::CA( int  x)
11 【转载】LoadLibrary调用DLL中的Class    : _x(x)
12 【转载】LoadLibrary调用DLL中的Class {
13【转载】LoadLibrary调用DLL中的Class    std::cout << "contructor" << std::endl;
14【转载】LoadLibrary调用DLL中的Class}

15 【转载】LoadLibrary调用DLL中的Class
16 【转载】LoadLibrary调用DLL中的Class CA:: ~ CA()
17 【转载】LoadLibrary调用DLL中的Class {
18【转载】LoadLibrary调用DLL中的Class    std::cout << "destructor" << std::endl;
19【转载】LoadLibrary调用DLL中的Class}

20 【转载】LoadLibrary调用DLL中的Class
21 【转载】LoadLibrary调用DLL中的Class int  CA::Func0()
22 【转载】LoadLibrary调用DLL中的Class {
23【转载】LoadLibrary调用DLL中的Class    return _x;
24【转载】LoadLibrary调用DLL中的Class}

25 【转载】LoadLibrary调用DLL中的Class
26 【转载】LoadLibrary调用DLL中的Class int  CA::Func( int  x)
27 【转载】LoadLibrary调用DLL中的Class {
28【转载】LoadLibrary调用DLL中的Class    return _x * x;
29【转载】LoadLibrary调用DLL中的Class}

30 【转载】LoadLibrary调用DLL中的Class
31 【转载】LoadLibrary调用DLL中的Class const  std:: string &  CA::FuncS( int  x,  const  std:: string   & str)  const
32 【转载】LoadLibrary调用DLL中的Class {
33【转载】LoadLibrary调用DLL中的Class    return str;
34【转载】LoadLibrary调用DLL中的Class}

35 【转载】LoadLibrary调用DLL中的Class

    这里需要.def文件了,因为Class在DLL中的命名不像函数命名那么简单,会被转义的,像CA::Func(int)在DLL的export表中就是?Func@CA@@QAEHH@Z ,具体定义说明可参看《xxx的自我修养》一书。因此,这里需要使用.def文件对函数进行重命名,下面是DllMain.def文件内容:
 
1 【转载】LoadLibrary调用DLL中的ClassLIBRARY TESTDLL
2 【转载】LoadLibrary调用DLL中的Class EXPORTS
3 【转载】LoadLibrary调用DLL中的Class     Func  =  Func
4 【转载】LoadLibrary调用DLL中的Class     CA::CA( int =   ?? 0CA@@QAE@H@Z
5 【转载】LoadLibrary调用DLL中的Class     CA:: ~ CA  =   ?? 1CA@@QAE@XZ
6 【转载】LoadLibrary调用DLL中的Class     CA::Func0  =   ? Func0@CA@@QAEHXZ
7 【转载】LoadLibrary调用DLL中的Class     CA::Func( int =   ? Func@CA@@QAEHH@Z
8 【转载】LoadLibrary调用DLL中的Class     ;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 【转载】LoadLibrary调用DLL中的Class     CA::FuncS  =   ? FuncS@CA@@QBEABV ? $basic_string@DU ? $char_traits@D@std@@V ? $allocator@D@ 2 @@std@@HABV23@@Z


    多说一句,这里.def的编写很需要Depends(Dependency Walker)工具的支持,其是查看DLL的首选工具啊。。 
【转载】LoadLibrary调用DLL中的Class

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

59【转载】LoadLibrary调用DLL中的Class    FreeLibrary(hdll);
60【转载】LoadLibrary调用DLL中的Class    
61【转载】LoadLibrary调用DLL中的Class    return 0;
62【转载】LoadLibrary调用DLL中的Class}


    结果还算正常: 
1 【转载】LoadLibrary调用DLL中的Class100
2 【转载】LoadLibrary调用DLL中的Class contructor
3 【转载】LoadLibrary调用DLL中的Class 5
4 【转载】LoadLibrary调用DLL中的Class 50
5 【转载】LoadLibrary调用DLL中的Class hello world
6 【转载】LoadLibrary调用DLL中的Class destructor
7 【转载】LoadLibrary调用DLL中的Class


    上面的代码基本演示了DLL中Class的简单使用,包括对contructor、destrunctor的调用,有参、无参、多参函数调用,不知道有啥缺陷,但至少Work了,嘿嘿~ 
    由上述代码可以看出,这种“显式”使用DLL中的Class是非常繁琐和危险的事情,因此我觉得能用“隐式”就不要用“显式”,能静态就不要用动态。。。 
    注意到没,代码没有演示继承和虚函数,那是因此我加入Virtual函数,程序就会core,实在搞不定,这里也就没法给出好的方案来,不知道哪位有啥建议么。。。
    上面代码参考了如下地址: 
     http://www.codeproject.com/dll/classesexportedusingLL.asp 
     http://blog.csdn.net/jdcb2001/archive/2006/11/21/1401569.aspx