zoukankan      html  css  js  c++  java
  • C++创建自己的库文件(dll文件创建和编译)

    创建编译库文件有个好处就是不容易被修改,加密的,方便调用,但是缺点是不容易查看其中的内容,反编译比较麻烦。下面让我们使用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就可以看到运行结果了。因为我为了让压缩包变小所以删除了过程文件,会提示你重新编译,单击确定即可。

  • 相关阅读:
    Codeforces 834E The Bakery【枚举+数位dp】
    Codeforces 834D The Bakery【dp+线段树维护+lazy】
    Codeforces Round #426 (Div. 2)【A.枚举,B.思维,C,二分+数学】
    暑期英语学习(词组积累)【持续更新中】
    “玲珑杯”ACM比赛 Round #19题解&源码【A,规律,B,二分,C,牛顿迭代法,D,平衡树,E,概率dp】
    关于前端的photoshop初探的学习笔记
    2017 Multi-University Training Contest
    BZOJ 1041: [HAOI2008]圆上的整点【数论,解方程】
    微信公众平台教程,注册申请、认证、开发、推广营销,教你怎么用微信公众号
    微信电视2.0版将新增语音搜索、节目单分享推荐自定义等
  • 原文地址:https://www.cnblogs.com/2008nmj/p/7059437.html
Copyright © 2011-2022 走看看