28
2014
07

C++windows内核编程笔记day11 win32静态库和动态库的使用

windows库程序:

静态库:

源代码被链接到调用的程序或动态库,被调用时,代码最少有1份,文件后缀.LIB


动态库: 函数被程序或其他动态库调用,被调用时,代码只有1份,文件后缀.DLL



静态库(C语言):

创建时,选择文本类型文件,输入Clib.c,设置输出路径 ../lib/Clib.lib



int Clib_add(int a,int b)

{

return a+b;

}

同一上工作区,建立控制台程序(.c文件)调用静态库:

#include<STDIO.H>

#pragma comment(lib,"../lib/Clib.lib") //包含静态库文件

//可以在 工程-设置-连接-对象/库模块 中加入静态库相对地址 ../lib/Clib.lib

int main()

{

int sum=Clib_add(12,34);

printf("12+34 结果是:%d\n",sum);

return 0;

}



C++程序调用C++静态库,与C中大部分一样,但调用之前,要写函数声明。

C++程序调用C静态库,写函数声明时,前面加 extern "C".


使用静态库示例:


新建 win32 static library工程(Clib):


新建一个文件,Clib.c,代码:

int Clib_add(int a,int b)
{
return a+b;
}
int Clib_sub(int a,int b)
{
return a-b;
}


生成,产生一个 Clib.lib文件。

新建C控制台程序,使用静态库,代码:

#include<STDIO.H>
#pragma comment(lib,"../lib/Clib.lib") //包含静态库文件
//可以在 工程-设置-连接-对象/库模块 中加入静态库相对地址 ../lib/Clib.lib
int main()
{
int sum=Clib_add(12,34);
printf("12+34 结果是:%d\n",sum);
return 0;
}



动态库:

(项目:Cdll):

在函数前加 _declspec(dllexport),声明方式导出动态库函数地址到.lib。

生成的.dll和.lib(.lib要手动复制到lib文件夹)。



C程序调用:

#pragma comment(lib,"../lib/Cdll.lib")//函数地址文件

//在运行时,Cdll.dll文件要放在与程序同一目录中或系统PATH目录中

//(隐式链接动态库dll)





C++程序调用C++动态库,与C中大部分一样,但调用之前,要写函数声明。

C++程序调用C动态库,写函数声明时,前面加 extern "C".



显式链接dll的方法(不使用lib文件,要建立.def文件):

1.定义函数指针类型

2.加载动态库

3.获取函数地址

4.使用函数

5.卸载动态库

.def文件格式:

LIBRARY CPPdll

EXPORTS

  CPPdll_add @1

  CPPdll_sub @2

  CPPdll_multi @3

示例:


新建动态库Cdll项目,win32 Dynamic-link library


新建一个Cdll.c文件,内容:

_declspec(dllexport) int Cdll_add(int a,int b)
{
return a+b;
}


新建一个c控制台程序,使用动态库,内容:

#include <STDIO.H>
#pragma comment(lib,"../lib/Cdll.lib")//函数地址文件
//.dll文件要放在与程序同一目录中
int main()
{
int sum=Cdll_add(34,56);
printf("34+56=%d\n",sum);
return 0;
}



C++中使用示例:


//CPPdll项目中:


//CPPdll.cpp

_declspec(dllexport) int CPPdll_add(int a,int b)
{
return a+b;
}


//CPPdll.def

LIBRARY CPPdll
EXPORTS
  CPPdll_add @1


编译生成dll和lib,

新建测试项目调用CPPdll和Cdll

#include<STDIO.H>
#pragma comment(lib,"../lib/CPPdll.lib")//C++调用c++的动态库
#pragma comment(lib,"../lib/Cdll.lib")//c++调用c的动态库
extern "C" _declspec(dllexport)  int Cdll_add(int a,int b);
_declspec(dllexport) int CPPdll_add(int a,int b);
int main()
{
int sum=CPPdll_add(23,45);
printf("23+45=%d\n",sum);
 int sum2=Cdll_add(231,45);
 printf("231+45=%d\n",sum2);
return 0;
}



附:显示调用CPPdll


#include <STDIO.H>

#include <WINDOWS.H>

//动态库加.def 文件申明函数地址

typedef int(*DLL_ADD)(int a,int b);//函数类型

int main()

{

HINSTANCE dll= LoadLibrary("CPPdll.dll");//加载动态库

DLL_ADD add=(DLL_ADD)GetProcAddress(dll,"CPPdll_add");

int sum=add(23,45);

printf("23+45=%d\n",sum);

FreeLibrary(dll);

return 0;

}


动态库中的类定义:

//dllclass.h文件,可以公开给调用方

#ifndef DLLCLASS_H
#define DLLCLASS_H
#ifdef DLLCLASS_EXPORTS     //在动态库.cpp中要定义,来表示导出
#define EXT_CLASS _declspec(dllexport) //cpp文件使用,导出
#else
#define EXT_CLASS _declspec(dllimport) //别人调用,导入
#endif
class EXT_CLASS CMath
{
public:
int add(int a,int b);
};
#endif


//dllclass.cpp文件

#define DLLCLASS_EXPORTS
#include <WINDOWS.H>
#include <STDIO.H>
#include "dllclass.h"
//动态库入口函数,返回false则表示调用不成功
BOOL CALLBACK DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH://进程加载,初始化
{
printf("loading dll ……\n");
}
break;
case DLL_PROCESS_DETACH://进程卸载,清理资源
{
printf("unloading dll ……\n");
}
break;
}
return true;
}
int CMath::add(int a,int b)
{
return a+b;
}



//调用

#include "../dllclass/dllclass.h"//包含类声明文件
#pragma comment(lib,"../lib/dllclass.lib") //包含库文件
int main()
{
CMath math;
int sum3=math.add(3,4);
cout<<"3+4 结果是:"<<sum3<<endl;
return 0;
}




版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。