库链接

库分为静态库和动态库。静态库与可执行文件打包,动态库与可执行文件独立。静态库加载需要.lib和.h文件。动态库隐式加载需要.dll、.h、.lib文件,显示加载只需要.dll文件

静态库

在链接阶段库将会与目标汇编后的目标文件.o一起打包生成可执行文件。成为可执行文件的一部分,后续此库就可以消失了。也就是说在编译的最后一步(链接阶段),如果程序需要使用静态库,在这一步都会一起打包到可执行文件中

生成

//  头文件
#ifndef _MYLIB_H_
#define _MYLIB_H_

void fun(int a);

extern int k;

class testclass
{
public:
  testclass();
  void print();
};
#endif
//  定义
#include "stdafx.h"
#include "testlib.h"
#include <iostream>
using namespace std;

void fun(int a)
{
  cout << "a: "+a << endl;   
}

int k = 222;

void testclass::print()
{
  cout << "k: " + k << endl;
}

testclass::testclass()
{
  cout << "init" << endl;
}

加载

vs2010加载静态库需要 接口头文件、.lib库文件

#include "stdafx.h"
#include "testlib.h"
#include <iostream>
using namespace std;

// 也可使用项目附加库目录
#pragma comment(lib,"testlib.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 23;
    cout << "a: "<< a << endl;

    return 0;
}

动态库

动态库在编译阶段都不会有什么动作,只有在程序运行时才被加载,也就是动态库的链接是发生在程序运行时期的,它和可执行文件是分开的,只是可执行文件在运行的某个时期调用了它

生成

动态库生成两个有用文件,一个是.lib,一个是dll。这里的.lib本质上不同于静态库中的.lib。这里的.lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体实现。而静态库中的lib包含了索引和实现

vs2010中新建

新建项目=》win32项目=》dll 勾选空项目
https://jingyan.baidu.com/article/5bbb5a1bd4a7bd13eaa17968.html

// 头文件
// 动态库生成的时候需要在接口前加上__declspec(dllexport),而导入的时候需要加__declspec(dllimport)
#ifdef DLL_EXPORTS
#define DLL_API_XYG __declspec(dllexport)
#else
#define DLL_API_XYG __declspec(dllexport)
#endif

class DLL_API_XYG Cdll
{
public:
    Cdll(void);
};

extern DLL_API_XYG int ndll;

extern "C" DLL_API_XYG int add(int x, int y);
// 定义
#include "stdafx.h"
#include "testdll.h"

DLL_API_XYG int ndll = 6;

DLL_API_XYG int add(int x, int y)
{
    return x + y;
}

Cdll::Cdll(void)
{
}

加载

隐式加载

需要接口头文件,dll文件,lib文件
文件位置:.h和.lib加载方式与静态加载完全一致。但.dll文件必须放在环境变量指定的目录下。当然通常是与目标.exe文件放在一起

#include "stdafx.h"
#include "testdll.h"

// 也可使用项目附加库目录
#pragma comment(lib, "testdll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
  printf("%d \n", add(22, 33));
  getchar();

  return 0;
}

显示加载

只需要dll

#include "stdafx.h"
// #include "testdll.h"
#include <Windows.h>

typedef int(*DLLDEMOFUNC)(int , int);
int _tmain(int argc, _TCHAR* argv[])
{
  DLLDEMOFUNC dllFunc = nullptr;
  HINSTANCE hDll;

  //  动态加载dll
  hDll = LoadLibrary(L"testdll.dll");

  //  根据函数名获取dll地址
  dllFunc = (DLLDEMOFUNC)GetProcAddress(hDll, "add");

  printf("%d \n", dllFunc(22, 23));
  getchar();

  //  卸载dll
  FreeLibrary(hDll);

  return 0;
}
posted @ 2019-11-19 13:31  熊云港  阅读(232)  评论(0编辑  收藏  举报