现在的位置: 首页 > 综合 > 正文

Windows库(笔记备忘)

2018年04月30日 ⁄ 综合 ⁄ 共 4294字 ⁄ 字号 评论关闭

一 Windows的库
  由于项目的复杂程度,或者为了提高代码的
  重用率等等,所以才引入了库程序。
  库包含两种:
    1 静态库:扩展名为LIB的文件,是不能被
        加载的程序,可以理解为目标程序的
        归档。
    2 动态库:扩展名是DLL的文件,是可以被
        应用程序加载的程序。
        
二 静态库

  1 静态库的特点
    1.1 目标程序的归档
    1.2 静态库的代码会被嵌入到程序当中。
    1.3 程序执行时不需要静态库存在

  2 C语言静态库
    2.1 创建静态库
        创建Win32静态库项目,使用*.C文件建立
        项目。
    2.2 添加静态库函数
    2.3 在程序中将静态库导入
       2.3.1 项目的Setting里设置
       2.3.2 使用关键字 pragma
        #pragma comment(lib, "../lib/winclib.lib")
    2.4 使用静态库提供的函数
       在C语言程序中,直接使用函数即可。
       
  3 C++语言的静态库
    3.1 创建静态库
       创建Win32静态库项目,使用*.CPP文件建立
       项目。
    3.2 添加静态库的函数
    3.3 导入静态库
       3.3.1 项目的Setting里设置
       3.3.2 使用关键字 pragma
        #pragma comment(lib, "../lib/wincpplib.lib")
    3.4 定义库函数的原形
       int CPP_Add( int nAdd1, int nAdd2 );
    3.5 使用库函数
    3.6 注意:
       如果在CPP文件使用C语言静态库,定义的
       静态库函数原形,需要增加 extern "C".
       例如:
       extern "C" int C_Add( int nAdd1, int nAdd2 );

Windows DLL中变量和类的使用方法类似:

一、变量的使用

建立(empty)DLL动态库 Dll_Value:

右键工程-设置-常规-输出文件-“../lib”:(输出文件为:Dll_Value.lib)

右键工程-设置-常规-链接(Link)-“../bin/Dll_Value.dll”

1.定义变量:

新建cpp文件

//导出方式①

__declspec(dllexport) int g_nValue = 100;
//导出方式②DEf
int g_nValue2 = 200;

//导出方式②:写入DEf文件

          新建文本文件dll_value.def

LIBRARY Dll_Value

EXPORTS

         g_nValue2       @1    DATA

2.导入lib文件

#pragama comment(lib, "../lib/Dll_Value.lib")

3.定义变量、.使用

#include "StdAfx.h"
#pragma  comment(lib, "../lib/Dll02.lib")

extern __declspec(dllimport) int g_nValue;
extern __declspec(dllimport) int g_nValue2;

int main()
{

printf("Value:%d\n",g_nValue);
printf("Value2:%d\n",g_nValue2);

return 0;
}

二、类的使用

建立(empty)DLL动态库 Dll_Class:

右键工程-设置-常规-输出文件-“../lib”:(输出文件为:Dll_Class.lib)

右键工程-设置-常规-链接(Link)-“../bin/Dll_Class.dll”

1.定义变量:

新建头文件CMath

#ifndef _CMATH_H_
#define _CMATH_H_

class __declspec(dllexport) CMath
{
public:
int Add(int nAdd1, int nAdd2);
int Sub(int nSub1, int nSub2);
};

#endif //_CMATH_H_

新建cpp文件:

#include "CMath.h"
int CMath::Add(int nAdd1, int nAdd2)
{
return nAdd1 + nAdd2;
}

int CMath::Sub(int nSub1, int nSub2)
{
return nSub1 - nSub2;
}

2.导入lib文件

#pragama comment(lib, "../lib/Dll_Class.lib")

3.定义类、使用

#include "StdAfx.h"
#pragma  comment(lib, "../lib/Dll02.lib")
class __declspec(dllimport) CMath
{
public:
int Add(int nAdd1, int nAdd2);
int Sub(int nSub1, int nSub2);
};

int main()
{

CMath m;
printf("Value:%d\n",m.Add(11,11));
printf("Value2:%d\n",m.Sub(9,99));
return 0;
}

/************/常用DLL类导出方式:

#ifndef _CMATH_H_
#define _CMATH_H_


#define _DLL_CLASS_

#ifdef _DLL_CLASS_
#define  _DLL_CLASS_EXT_ __declspec(dllexport)
#else
#define _DLL_CLASS_EXT_  __declspec(dllimport)

#endif _DLL_CLASS_

#endif //_CMATH_H_

使用时直接包含头文件即可如下:

#include "StdAfx.h"
#pragma  comment(lib, "../lib/Dll02.lib")
extern __declspec(dllimport) int g_nValue;
extern __declspec(dllimport) int g_nValue2;
#include "../Dll02/math.h"
/*
class __declspec(dllimport) CMath
{
public:
int Add(int nAdd1, int nAdd2);
int Sub(int nSub1, int nSub2);
};
*/
int main()
{
CMath m;
printf("Value:%d\n",m.Add(11,11));
printf("Value2:%d\n",m.Sub(9,99));
return 0;
}

/*****************************************************************/

DLL中调用函数分为隐式调用和显式调用:

DLL源文件CPP:

__declspec(dllexport) int DLL_Add(int nAdd1, int nAdd2) //C++方式编译
{
return nAdd1 + nAdd2;
}

extern "C" __declspec(dllexport) int DLL_Sub(int nSub1, int nSub2)//C方式编译
{

return nSub1 - nSub2;
}

int  DLL_Mul(int nMul1, int nMul2)//配合def文件
{
return nMul1 * nMul2;
}

导入def文件

LIBRARY Dll_Func
EXPORTS
   DLL_Mul    @1 

编译生成DLL,lib时 设置-常规-输出文件-“../lib”     设置-连接-输出文件名-“../bin/DLLXX.dll”

1、隐式调用

#include <stdio.h>

//隐式链接加载DLL,设置-连接-输出文件名-“../bin/UseDll_Func.exe”
#pragma comment(lib, "../lib/Dll_Func.lib")

int DLL_Add(int nAdd1, int nAdd2);
extern "C" int DLL_Sub(int nSub1, int nSub2);
int DLL_Mul(int nMul1, int nMul2);

int main()
{
 
int nAdd = DLL_Add(100,100);
printf("nAdd:%d \n",nAdd);

int nSub = DLL_Sub(100,100);
printf("nSub:%d \n",nSub);

int nMul = DLL_Mul(100,100);
printf("nMul:%d \n",nMul);

return 0;
}

2.显式调用

#include <windows.h>
#include <stdio.h>

//测试显式连接调用DLLFunc

typedef int (*DLL_ADD)(int a, int b);
typedef int (*DLL_SUB)(int a, int b);
typedef int (*DLL_MUL)(int a, int b);

void UseFunc()
{
   HMODULE hDll = (HMODULE)LoadLibrary("Dll_Func.dll");
   if (NULL == hDll)
   {
       perror("LoadDll err \n");
  return;
   }
   printf("%p \n", hDll);
  
   DLL_ADD DLL_Add = (DLL_ADD)GetProcAddress(hDll, "DLL_Add");//此函数用__declspec(dllexport) C++编译器编译后函数名不在是DLL_Add所以找不到该函数
   if (NULL == DLL_Add )
   {
  perror("Load Add err \n");
   }
   
   DLL_SUB DLL_Sub = (DLL_SUB)GetProcAddress(hDll, "DLL_Sub");
   if (NULL == DLL_Sub)
   {
  perror("Load Add err \n");
   }
   else
   {   

  int nSub = DLL_Sub(100,90);
  printf("nSub:%d \n",nSub);
   }

   DLL_MUL DLL_Mul = (DLL_MUL)GetProcAddress(hDll, "DLL_Mul");
   if (NULL == DLL_Mul)
   {
  perror("Load Add err \n");
   }
   else
   {
  int nMul = DLL_Mul(10,90);
  printf("%d \n",nMul);
   }
   
  FreeLibrary(hDll);
}

int main()
{

    UseFunc();

return 0;
}

抱歉!评论已关闭.