• 库链接


    库分为静态库和动态库。静态库与可执行文件打包,动态库与可执行文件独立。静态库加载需要.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 
    ", 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 
    ", dllFunc(22, 23));
      getchar();
    
      //  卸载dll
      FreeLibrary(hDll);
    
      return 0;
    }
    
  • 相关阅读:
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
    Only one instance of a ScriptManager can be added to the page.
    springboot SSM
    spring mvc 请求转发和重定向
    Spring Boot 配置 Swagger2 接口文档引擎
    solr
    jQuery
    反向代理负载均衡-Nginx
    mybatis二级缓存
    Vue的路由
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/11888722.html
Copyright © 2020-2023  润新知