zoukankan      html  css  js  c++  java
  • 浅谈Windows中DLL导出类

    一般的DLL导出类方法,一个简单的例子:

    dllExample.h:

     1 #pragma once
     2 
     3 #ifdef DLL_EXPORTS
     4 #define DLL_API __declspec(dllexport)
     5 #else
     6 #define DLL_API __declspec(dllimport)
     7 #endif
     8 
     9 class DLL_API ExportClass
    10 {
    11 pirvate:
    12     int x;
    13 public:
    14     void foo();
    15 };

    dllExample.cpp:

    1 #define DLL_EXPORTS
    2 #include "dllExample.h"
    3 
    4 void ExportClass::foo()
    5 {
    6     //do something...
    7     return;
    8 }

    而外部代码只需要包含头文件,就会自动导入ExportClass的定义。
    编译时连接该DLL对应的lib,运行时提供DLL文件,即可正常运行。

    不过这种简单的DLL导出存在一个限制,如果我们导出的类中含有非C++基础类型:

    dllExample.h:

     1 #pragma once
     2 
     3 #ifdef DLL_EXPORTS
     4 #define DLL_API __declspec(dllexport)
     5 #else
     6 #define DLL_API __declspec(dllimport)
     7 #endif
     8 
     9 class DLL_API ExportClass
    10 {
    11 pirvate:
    12     std::string x; //此处的string类型导出是不安全的
    13 public:
    14     void foo();
    15 };

    我们知道, 对于STL,微软为每个版本的VS都有不同的实现,VS2008(VC90),VS2010(VC100),VS2013(VC120)。
    由于不同的STL的实现,我们不能在不同的版本见直接传递std::string, 否则运行期可能出现不可预知的错误。
    而事实上我们在ExportClass中的std::string x变量是不希望被外部直接使用的,也就是并没有export的必要,事实上,不建议让dll向外导出任何关于非C++基础类型的定义。
    但是由于ExportClass需要向外导出(因为需要使用foo()函数),应该如何处理这样的矛盾呢?

    对于这样的问题,我们需要使用C++的抽象类(其实就是java中的interface概念)来解决:
    我们需要:
    1. 申明一个只有纯虚函数和C++基础类型的基类,所有需要向外部导出的定义都包含在该类中。
    2. 申明另一个类,继承该基类。
    3. 实现一个返回基类函数指针的getInstance函数,即返回一个派生类实例的工厂方法。
    4. 在外部代码中,通过多态机制访问该类。

    dllExample.h:

     1 #pragma once
     2 
     3 #ifdef DLL_EXPORTS
     4 #define DLL_API __declspec(dllexport)
     5 #else
     6 #define DLL_API __declspec(dllimport)
     7 #endif
     8 
     9 class DLL_API ExportInterface
    10 {
    11 public:
    12     virtual void foo() = 0;
    13 };
    14 
    15 extern "C" DLL_API ExportInterface*  getInstance();
    16 
    17 #ifdef DLL_EXPORTS  //我们并不需要向外导出该类的定义,在外部代码编译时,也不需要包含此类的定义。
    18 class ExportClass: public ExportInterface
    19 {
    20 pirvate:
    21     std::string x; //由于外部代码对此不可见,此处的std::string是安全的。
    22 public:
    23     void foo(); //函数体在dllExample.cpp中实现
    24 };
    25 #endif

    dllExample.cpp:

    #define DLL_EXPORTS
    #include "dllExample.h"
    
    extern "C" DLL_API ExportInterface* getInstance()
    {
        ExportInterface* pInstance = new ExportClass();
        return pInstance;
    }
    
    void ExportClass::foo()
    {
        //do something...
        return;
    }
  • 相关阅读:
    Rainmeter 雨滴桌面 主题分享
    行人检測之HOG特征(Histograms of Oriented Gradients)
    const和readonly差别
    ADB命令解析
    Java实现 蓝桥杯VIP 算法训练 接水问题
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
  • 原文地址:https://www.cnblogs.com/JingJ/p/4442286.html
Copyright © 2011-2022 走看看