C++编写一个简单的DLL

  • 什么是DLL:

自从微软推出16位的Windows操做系统起,此后每种版本的Windows操做系统都很是依赖于动态连接库(DLL)中的函数和数据,实际上 Windows操做系统中几乎全部的内容都由DLL以一种或另一种形式表明着,例如显示的字体和图标存储在GDI DLL中、显示Windows桌面和处理用户的输入所须要的代码被存储在一个User DLL中、Windows编程所须要的大量的API函数也被包含在Kernel DLL中。
html

DLL是创建在客户/服务器通讯的概念上,包含若干函数、类或资源的库文件,函数和数据被存储在一个DLL(服务器)上并由一个或多个客户导出而使用,这些客户能够是应用程序或者是其它的DLL。DLL库不一样于静态库,在静态库状况下,函数和数据被编译进一个二进制文件(一般扩展名为*.LIB), Visual C++的编译器在处理程序代码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其余模块组合在一块儿生成可执行文件。这个过程称为"静态连接",此时由于应用程序所需的所有内容都是从库中复制了出来,因此静态库自己并不须要与可执行文件一块儿发行。
ios

在动态库的状况下,有两个文件,一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件连接到所须要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,所以在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码连接起来,从而节省了内存资源。从上面的说明能够看出,DLL和.LIB文件必须随应用程序一块儿发行,不然应用程序将会产生错误。
编程

微软的Visual C++支持三种DLL,它们分别是Non-MFC Dll(非MFC动态库)、Regular Dll(常规DLL)、Extension Dll(扩展DLL)。Non-MFC DLL指的是不用MFC的类库结构,直接用C语言写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用。Regular DLL:和下述的Extension Dlls同样,是用MFC类库编写的,它的一个明显的特色是在源文件里有一个继承CWinApp的类(注意:此类DLL虽然从CWinApp派生,但没有消息循环),被导出的函数是C函数、C++类或者C++成员函数(注意不要把术语C++类与MFC的微软基础C++类相混淆),调用常规DLL的应用程序没必要是MFC应用程序,只要是能调用类C函数的应用程序就能够,它们能够是在Visual C++、Dephi、Visual Basic、Borland C等编译环境下利用DLL开发应用程序。
windows

  • DLL的建立:

打开VS2013,选择Win32:服务器

选择DLL:函数

里边会自动为你添加好几个文件:测试

以及一个dllmain的格式,这里面是,当加载一个DLL(ATTACH)或者释放一个DLL(DETACH)等不一样状态发生时,所要执行的代码(只不过下面的代码是当四个状态发生时什么都不执行):字体

参数中,hMoudle是动态库被调用时所传递来的一个指向本身的句柄(实际上,它是指向_DGROUP段的一个选择符); ul_reason_for_call是一个说明动态库被调缘由的标志,当进程或线程装入或卸载动态连接库的时候,操做系统调用入口函数,并说明动态连接库被调用的缘由,它全部的可能值为:DLL_PROCESS_ATTACH: 进程被调用、DLL_THREAD_ATTACH: 线程被调用、DLL_PROCESS_DETACH: 进程被中止、DLL_THREAD_DETACH: 线程被中止;lpReserved为保留参数。spa

咱们直接在testDLL.cpp中添加代码,这里保存的是DLL的导出函数:操作系统

extern "C" __declspec(dllexport) int add(int a, int b) 
{
    return (a + b);
}

extern "C" __declspec(dllexport) int sub(int a, int b)
{
    return (a - b);
}

编译生成一个testDLL.dll.下面进行测试:

隐式链接:

#include <iostream>
#include <windows.h>

#pragma comment(lib,"testDLL.lib")
extern "C"_declspec(dllimport) int add(int a, int b);
extern "C"_declspec(dllimport) int sub(int a, int b);
int main()
{
    int nParam1 = 9;
    int nParam2 = 3;
    int nAdd = add(nParam1, nParam2);
    int nSub = sub(nParam1, nParam2);
    std::cout << nAdd << ":" << nSub << std::endl;
    system("pause");
    return 0;
}

显示连接:

#include <iostream>
#include <windows.h>

int main()
{
    typedef int (*_pAdd)(int a, int b);
    typedef int (*_pSub)(int a, int b);
    HINSTANCE hDll = LoadLibrary("testDLL.dll");
    int nParam1 = 9;
    int nParam2 = 3;
    _pAdd pAdd = (_pAdd)GetProcAddress(hDll, "add");
    _pSub pSub = (_pSub)GetProcAddress(hDll, "sub");
    int nAdd = pAdd(nParam1, nParam2);
    int nSub = pSub(nParam1, nParam2);
    std::cout << nAdd << ":" << nSub << std::endl;
FreeLibrary(hDll); system(
"pause"); return 0; }

正确输出结果:

 

参考:

http://www.cnblogs.com/daocaoren/archive/2012/05/30/2526495.html

相关文章
相关标签/搜索