c/c++调用dll

1、lib.h

 1 #ifndef LIB_H  2 #define LIB_H  3  4 #include <windows.h>  5 #include <iostream>  6  7 using namespace std;  8  9 extern "C" int __declspec(dllexport)add(int,int); 10 extern "C" int __declspec(dllexport)sub(int,int); 11 12 //int add(int,int); 13 //int sub(int,int); 14 15 #endif 
lib.h

2、lib.cpp

 1 #include "lib.h" 

 2 

 3 /*BOOL APIENTRY DllMain(HANDLE hModule,

 4        DWORD ul_reason_for_call,

 5        LPVOID lpReserved){

 6     switch(ul_reason_for_call){

 7         case DLL_PROCESS_ATTACH:

 8         case DLL_THREAD_ATTACH:

 9         case DLL_THREAD_DETACH:

10         case DLL_PROCESS_DETACH:

11         break;

12     }

13     return TRUE;

14 }*/

15 

16 int add(int x, int y) 

17 { 

18     return x + y; 

19 }

20 int sub(int x, int y) 

21 { 

22     return x - y; 

23 }

24     
lib.cpp

3、main.cpp

 1 #include "lib.h"

 2 

 3 int main(){

 4     //DLL句柄声明

 5     //HINSTANCE hDll;

 6     HMODULE  hDll;

 7     

 8     //加载DLL,返回句柄:

 9     //HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);

10     //hDll=LoadLibrary(_T("lib.dll"));

11     hDll=LoadLibrary(TEXT("lib.dll"));//hDll=LoadLibrary("lib.dll");

12     if(hDll==NULL)

13         cout << "dll加载失败!" << endl;

14     cout << "dll加载成功!" << endl;

15     cout << "dll句柄:" << hDll <<endl;

16     

17     //定义与add函数接受参数类型和返回值均相同的函数指针类型

18     typedef int(*lpAddFun)(int,int);

19     typedef int(*lpSubFun)(int,int);

20 

21     lpAddFun addFun;

22     lpSubFun subFun;

23     

24     //

25     //GetProcAddress函数原型:

26     //FARPROC GetProcAddress(

27     //HMODULE hModule,        // DLL模块句柄

28     //LPCSTR lpProcName);    // 函数名

29     LPCSTR add="add";

30     LPCSTR sub="sub";

31     int *numFun;

32     

33     if(hDll!=NULL){

34         addFun=(lpAddFun)GetProcAddress(hDll,add);

35         cout << "addFun :" << addFun << endl;

36         subFun=(lpSubFun)GetProcAddress(hDll,sub);

37         cout << "subFun :" << subFun << endl;

38         numFun=(int *)GetProcAddress(hDll,"num");

39         cout << "numFun1:" << numFun << endl;

40         if(addFun!=NULL){

41             int result=addFun(3,2);

42             cout << "3+2=" << result << endl;

43         }

44         if(subFun!=NULL){

45             int result=subFun(3,2);

46             cout << "3-2=" << result << endl;

47         }

48         if(numFun!=NULL){

49             cout << "numFun2:"<< numFun <<endl;//没有num函数,就返回NULL

50         }

51         FreeLibrary(hDll);//释放DLL

52         cout << "dll卸载成功!";

53     }

54     return 0;

55 }
main.cpp

 4、编译lib.cpp为dll

  cl /LD lib.cpp

  生成lib.dll,同时还有lib.exp、lib.lib

5、编译main.cpp为main.exe

  cl main.cpp

6、DLL中导出函数的声明有两种方式:

  6.1、一种方式为例子中给出的:

    在函数声明中加上__declspec(dllexport)
  6.2、另外一种方式是采用模块定义(.def) 文件声明

    .def文件为链接器,提供了有关被链接程序的导出、属性及其他方面的信息。
    代码中lib.cpp中注释部分演示了怎样同.def文件,

    将函数add声明为DLL导出 函数(需在dllTest工程中添加lib.def文件)

       lib.def : 导出DLL函数
      LIBRARY libdll

      EXPORTS
      add @ 1
      .def文件的规则为:
        (1)LIBRARY语句说明.def文件相应的DLL;
        (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中
       的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调
       用时,这个序号将发挥其作用);
        (3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,
       且注释不能与语句共享一行。
    由此可以看出,例子中lib.def文件的含义为生成名为“libdll”
    的动态链接库,导出其中的add函数,并指定add函数的序号为1。

7、当使用第一种声明导出函数函数时,将"C"改为C++,

则main.cpp不能成功调用到lib.dll中的各个函数。

 

 

 

 

你可能感兴趣的:(c/c++)