• 动态链接库和静态链接库介绍和实例(三)


    动态链接库创建和使用实例

    生成和使用动态库

    生成动态库

     新建项目--win32项目--填写项目名--确定--下一步--应用程序类型:选择dll--附加选项:选择导出符号--完成

    可以看到生成了一个dllmain.cpp 文件,这是dll应用程序的入口,注意它和普通工程的入口main函数不同,这个文件我们不需要修改。

     在这个动态库中我们举例导出一个变量,一个类,一个函数,头文件dll.h如下:

    #pragma once
    //新建生成dll的工程时,vs默认定义了宏MYDLL_EXPORTS,因此,DLL_API 是 __declspec(dllexport),用来导出
    //当我们在静态调用dll时,我们包含该头文件,由于没有定义MYDLL_EXPORTS,所以DLL_API是
    //__declspec(dllimport),用来导入
    #ifdef MYDLL_EXPORTS
    #define DLL_API __declspec(dllexport)
    #else
    #define DLL_API __declspec(dllimport)
    #endif
    
    // 导出类
    class DLL_API Cdll {
    public:
    	Cdll(void);
    	void print();
    	// TODO: 在此添加您的方法。
    };
    
    //导出变量,变量在.cpp文件中定义
    extern DLL_API int ndll;
    
    //导出函数,加extern "C",是为了保证编译时生成的函数名不变,这样动态调用dll时才能
    //正确获取函数的地址
    extern "C" DLL_API int fndll(void);

    dll.cpp 文件如下:

    #include "dll.h"
    #include <iostream>
    using namespace std;
    // 这是导出变量的一个示例
    DLL_API int ndll = 6;
    
    // 这是导出函数的一个示例。
    DLL_API int fndll(void)
    {
    	return 42;
    }
    
    // 这是已导出类的构造函数。
    // 有关类定义的信息,请参阅 dll.h
    Cdll::Cdll()
    {
    	return;
    }
    
    void Cdll::print()
    {
    	cout << "this is a dll test!" << endl;
    }

    调用动态库

    有两种方法调用动态库,一种隐式链接,一种显示链接。

    调用动态库:隐式链接

    隐式链接 需要.h文件,dll文件,lib文件

    (1)添加头文件附加包含目录,讲.h文件路径添加到项目属性--C/C++--General--附加包含目录

    (2)设置项目属性--Linker--General--附加库目录为lib所在的路径

    (3)将lib文件名添加到项目属性--链接器--输入--附加依赖项(或者直接在源代码中加入#pragma comment(lib, “**.lib”))

    (4)在源文件中添加.h头文件

    然后就像平常一样调用普通函数、类、变量

    #include <iostream>
    #include "dll.h"
    using namespace std;
    
    int main()
    {
    	cout << ndll << endl;
    	cout << fndll() << endl;
    	Cdll dll;
    	dll.print();
    	system("pause");
    	return 0;
    }

    就可build成功。

    将dll放到项目的debug目录下

    就可以运行:

    调用动态库:显示链接

    显示链接 只需要.dll文件,但是这种调用方式不能调用dll中的变量或者类(其实可以调用类,但是相当麻烦,有兴趣者可参考http://blog.csdn.net/jdcb2001/article/details/1394883

    显示调用主要使用WIN32 API函数LoadLibrary、GetProcAddress,举例如下:

    #include <iostream>
    #include <Windows.h>
    using namespace std;
    
    typedef int(*dllfun)(void);//定义指向dll中函数的函数指针
    int main()
    {
    	HINSTANCE hlib = LoadLibrary("..\mydll.dll");
    	if (!hlib)
    	{
    		std::cout << "load dll error
    ";
    		return -1;
    	}
    	dllfun fun = (dllfun)GetProcAddress(hlib, "fndll");
    	if (!fun)
    	{
    		std::cout << "load fun error
    ";
    		return -1;
    	}
    	cout << fun() << endl;
    	system("pause");
    	return 0;
    }

    build运行结果:

    参考:http://www.cnblogs.com/TenosDoIt/p/3203137.html

  • 相关阅读:
    C# 全局变量
    [C#]续:利用键代码自动转换生成字母键或其它键信息
    [WPF](小结2)DataGrid嵌套DataGrid(也叫主从表)
    [C#]winform窗口托盘
    C# arrayList动态添加对象元素,并取出对象元素的方法
    [WPF](小结3)DataGridInTreeView树嵌表
    [WPF](小结4)TreeView的数据分层模板
    [WPF](小结1)ListBox嵌套ListBox
    [C#]利用键代码自动转换生成字母键或其它键信息
    [C#]使用API 获取设置系统热键和快捷键
  • 原文地址:https://www.cnblogs.com/oneDongHua/p/14264067.html
Copyright © 2020-2023  润新知