windows下制作与使用dll与lib

本文将详细介绍windows下如何制作.lib和.dll文件,并且还会介绍如果在项目中使用.lib和.dll文件。在进入正题之前,我们先来看看程序编译的四个过程。

程序编译的四个过程

windows下制作与使用dll与lib_第1张图片
从源文件到可执行文件中经历四个过程:
1.预编译:将原文件中头文件展开,宏定义处理(就是对宏定义进行替换)
2.汇编:对预编译处理好的.i文件进行语法检测,提示,生产.s文件,对其他错误不做检查(将高级语言翻译成汇编语言)
3.编译:对汇编处理好的.s文件进行编译,编译为机器能之间看得懂的语言(也就是0/1二进制)
4.链接:让调用函数和调用的目标文件与主目标文件链接,生成可执行文件。该过程会对没有进行定义而调用的函数进行报错

动态链接与静态链接

程序编译的链接环节有两种方式,分别是动态链接与静态链接。

静态链接

静态连接库就是把 (lib) ⽂件中⽤到的函数代码 直接链接进⽬标程序 ,程序运⾏的时候不再需要其它的库⽂件。

动态链接

动态链接通俗来讲就是随用随取,只有当程序运行是用到了所需要的模块,才会把dll文件加载进来,其好处就是当我们对dll文件进行替换,不需要重新编译整个程序,只需要更换dll文件即可。

windows下静态库的封装与使用

静态库的封装

首先我们在visual studio中新建一个空项目,之后添加两个文件test.h、test.cpp,项目整体如图所示:
windows下制作与使用dll与lib_第2张图片

之后在test.h中写入代码

#pragma once
#include
class myClass
{
public:
	myClass();
	void print();
};

test.cpp中写入代码

#include"test.h"
myClass::myClass()
{

}
void myClass::print()
{
	printf("hello lib");
}

之后右键单击staticlib项目,选择属性,并将配置类型修改为静态库。
windows下制作与使用dll与lib_第3张图片
之后编译程序,如图所示则静态库生成成功。
windows下制作与使用dll与lib_第4张图片

静态库的使用

新建项目libtest,并根据之前静态库生成的路径找到生成的静态库staticlib\x64\Debug\staticlib.lib以及staticlib\staticlib\test.h文件,并将其复制到libtest\lib文件夹中。
windows下制作与使用dll与lib_第5张图片
之后右键项目进入属性界面,选择C/C++ —> 常规 —>附加包含目录,将我们之前创建的lib文件夹加入路径。
windows下制作与使用dll与lib_第6张图片
之后再选择 链接器—>常规—>附加库目录,也是将lib文件加入其中。
windows下制作与使用dll与lib_第7张图片

最后进入 链接器–>输入—>附加依赖项,输入staticlib.lib
windows下制作与使用dll与lib_第8张图片
自此以后就可以再项目中使用我们之前封装过的lib文件里的myClass类了。

windows下制作与使用dll与lib_第9张图片
windows下制作与使用dll与lib_第10张图片

动态库的封装

visual studio 新建dll项目
windows下制作与使用dll与lib_第11张图片
创建plugin.h文件

#pragma once
#include
#include
using namespace std;

//此处的作用是告诉程序被PLUGIN_API 
//修饰的在dll文件中的变量会被外界调用
#ifdef DLL_EXPORTS
#define PLUGIN_API __declspec(dllexport)
#else
#define PLUGIN_API __declspec(dllimport)
#endif

class IPlugin
{
public:
    IPlugin() = default;
    virtual ~IPlugin() = default;
    IPlugin(const IPlugin&) = delete;
    IPlugin& operator=(const IPlugin&) = delete;
public:
    virtual string getVersionString() const = 0;
    //! \brief 获取业务名称
    //! \return
    virtual string getPluginName() const = 0;
    //! \brief 执行业务的主要接口方法
    //! \param msg 由外部程序发送的通讯协议(比如json报文)
    //! \return 错误信息
    virtual void exec(const string& msg) = 0;
    //! \brief 业务停止运行
    //! \return
    virtual void stop() { return; }
    //! \brief 释放动态库资源
    //! \return 错误信息
    virtual void release() = 0;
};

创建pluginTest.h文件

#pragma once
#include"plugin.h"

//用Test3继承IPlugin,并且在Test3中重写IPlugin中的纯虚函数,
//使得封装好的dll文件不会暴露内部具体实现的细节,只是对用户提供父类接口,
//在使用的时候通过外部调用getinstance()函数获取实例。
class Test3 : public IPlugin
{
public:
	Test3();
	virtual string getVersionString() const;
	//! \brief 获取业务名称
	//! \return
	virtual string getPluginName() const;
public:
	//! \brief 执行业务的主要接口方法
	//! \param msg 由外部程序发送的通讯协议(比如json报文)
	//! \return 错误信息
	virtual void exec(const string& msg);
	//! \brief 业务停止运行
	//! \return
	virtual void stop();
	//! \brief 释放动态库资源
	//! \return 错误信息
	virtual void release();
};
//此处一定要加 extern "C" PLUGIN_API 修饰,
//不然后面会找不到dll文件中的信息
extern "C" PLUGIN_API void *getinstance();

创建pluginTest.cpp文件

#include "pluginTest.h"
void* getinstance()
{
    return new Test3;
}
Test3::Test3()
{
}
string Test3::getVersionString() const
{
    return "3.0\n";
}
string Test3::getPluginName() const
{
    return "Test3\n";
}
void Test3::exec(const string& msg)
{
    printf("execute command %s\n", msg.c_str());
}
void Test3::stop()
{
    printf("program stop\n");
}
void Test3::release()
{
    printf("release plugram\n");
}

接着在项目属性中,设置配置类型为动态库(.dll)windows下制作与使用dll与lib_第12张图片
自此dll文件生成在了 ./x64/Debug目录下。
windows下制作与使用dll与lib_第13张图片

动态库的使用

创建新项目pluginTest,同静态库一样,将动态库生成的plugin.dll文件和plugin.h文件放到/pluginTest/lib文件夹中
windows下制作与使用dll与lib_第14张图片

将plugin.h加入项目,并且在pluginTest.cpp中写入代码

// pluginTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include "windows.h"
#include"plugin.h"
using namespace std;
typedef void* (*obj)();
int main()
{

    HINSTANCE hDLL;               // Handle to DLL
    obj instance;    // Function pointer
    //显示载入plugin.dll动态库
    hDLL = LoadLibrary(L"C:\\Users\\99352\\Desktop\\test\\pluginTest\\dll\\plugin.dll");
    if (NULL != hDLL)
    {
    	//用函数指针捕获plugin.dll中的void *getinstance();函数
        instance = (obj)GetProcAddress(hDLL, "getinstance");
        if (NULL != instance)
        {
            IPlugin* plugin = (IPlugin*)instance();
            plugin->exec("sas");
            plugin->release();
            plugin->stop();
            cout << plugin->getPluginName() << endl;
            cout << plugin->getVersionString() << endl;
        }
        else
        {
            // report the error
            cout << "error" << endl;
        }
        FreeLibrary(hDLL);
    }
    int a;
    cin >> a;
}

之后右键项目进入属性界面,选择C/C++ —> 常规 —>附加包含目录,将我们之前创建的lib文件夹加入路径。

windows下制作与使用dll与lib_第15张图片
之后再选择 链接器—>常规—>附加库目录,也是将lib文件加入其中。
windows下制作与使用dll与lib_第16张图片
之后就可以正常运行了
windows下制作与使用dll与lib_第17张图片

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