我的github

创建编译库文件有个好处就是不容易被修改,加密的,方便调用,但是缺点是不容易查看其中的内容,反编译比较麻烦。下面让我们使用VC创建编译自己的库文件吧。常用的函数,不常更改的,应该放到库文件里,所以库文件的意义非比寻常。但为了(这里需要明白C++库和C++组件(COM组件)、插件OCX的区别) DLL与COM面试问题        DLL和插件的相关性        插件是使用了某种规则的DLL       给自己的程序添加插件功能dll做插件         DLL插件设计思想       使用DLL作为插件的设计框架        插件开发(Java)          基于插件式的开发框架            插件技术(Android)

dll库中主要是一个函数,当然还有类和变量这些辅助对象,其主要目的是为了实现某个特定的功能,可以由任意程序调用。这跟静态库不同。

dll与lib的区别:lib是在编译时和可执行程序打包到一起的,外部看不到它的存在,它在exe里面,所以如果丢失了dll它依然可以运行。它是静态链接库,是目标对象obj的集合。而dll在导出时,有时没有lib文件,有时有lib文件,而存在的这种lib文件就是导出文件,到出库。这样的lib,导入文件,包含DLL导出的函数和变量的符号名,而真正的函数的实现和数据存在于DLL。lib占用内存,dll只用用时才占用内存

举个例子:

__declspec(dllexport)

声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类。

__declspec(dllimport)

声明一个导入函数,是说这个函数是从别的DLL导入。我要用。一般用于使用某个dll的exe中不使用__declspec(dllimport)也能正确编译代码,但使用__declspec(dllimport)使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于DLL中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨DLL边界的函数调用中。但是,必须使用__declspec(dllimport)才能导入DLL中使用的变量。

为什么叫导入文件,就是把Dll中导出的函数,类给导入到我们自己的应用程序中使用。

使用方法:1、静态链接库(lib),我们使用隐式链接; 2、动态链接库(DLL),不包含lib导入文件,我们用显式链接。但是这样会很麻烦,我不喜欢这样用,我会想尽方法让它带有lib文件。 3、动态链接库(DLL),包含lib导入文件,我们使用 隐式链接。

 1. 新建-->项目-->Win32 Console-->勾选dll-->确定。

 2. MyDll.h头文件声明

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport) //定义MYDLL_API为导出类型
#else
#define MYDLL_API __declspec(dllimport)
#endif

// This class is exported from the MyDll.dll 该类从MyDll.dll中导出
class MYDLL_API CMyDll {
public:
    CMyDll(void);
    CMyDll(int _age, char *_name); //年龄和姓名 构造函数
    ~CMyDll();
    // TODO: add your methods here.
    void Introduce(); //介绍函数
    static void SayStatic();
private:
    int age;
    char* name;
    static int a;
};

  extern MYDLL_API int nMyDll;//导出全局变量的声明
  extern MYDLL_API float f;
  extern MYDLL_API int a;

MYDLL_API int fnMyDll(void); //导出全局函数的声明
MYDLL_API void SayHell();

 3. MyDll.cpp文件的函数和类的实现

#include "stdafx.h"
#include "MyDll.h"
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;


// This is an example of an exported variable
MYDLL_API int nMyDll=0;
MYDLL_API float f = 3.14;
MYDLL_API int a = 23;

int CMyDll::a = 90; //全局变量

// This is an example of an exported function.
MYDLL_API int fnMyDll(void)
{
    return 42;
}
MYDLL_API void SayHell() //全局函数
{
    cout<<"Hello World!"<<endl;
}

//静态函数
void CMyDll::SayStatic()
{
    cout<<"我是类中的静态函数"<<endl;
    cout<<"类中静态变量初始化值是:a="<<CMyDll::a<<endl;
}

// This is the constructor of a class that has been exported.这是已导出类的构造函数
// see MyDll.h for the class definition有关该类的定义参阅MyDll.h
CMyDll::CMyDll():name(NULL)
{
    return;
}

CMyDll::~CMyDll()
{
    if(name != NULL)
    {
        delete[]name;
    }
}

CMyDll::CMyDll(int _age, char *_name):age(0), name(NULL)
{
    this->age = _age;
    if(_name != NULL)
    {
        int len = strlen(_name)+1;
        if(name==NULL)
        {
            name = new char[len];
        }
        strcpy_s(name, len, _name);
    }
}

void CMyDll::Introduce()
{
    cout<<"My name is yujianhui"<<endl;
    cout<<"Name:"<<name<<endl;
    cout<<"Age:"<<age<<endl;
}

 项目生成如下:

 测试:(这里属于静态加载,即lib和dll都存在的情况下)

 步骤:1.在程序中添加头文件;2.加载lib;3.使用。

示例:

#include<iostream>
#include "MyDll.h"
#pragma comment(lib, "MyDll")
using namespace std;

int main()
{
    cout<<a<<endl;
    cout<<f<<endl;
    SayHell();
    CMyDll mydll(24, "yujianhui");
    mydll.Introduce();
    CMyDll::SayStatic();
    system("pause");
}

 

程序下载:http://pan.baidu.com/s/1mhEqfxQ

程序介绍:VS2010版 使用方法:解压后,使用VS打开.sln文件,然后单击Debug->Start Without Debugging就可以看到运行结果了。因为我为了让压缩包变小所以删除了过程文件,会提示你重新编译,单击确定即可。

 

posted on 2017-06-21 14:40  XiaoNiuFeiTian  阅读(5387)  评论(0编辑  收藏  举报