zoukankan      html  css  js  c++  java
  • DLL 导出封装类

    首先使用Wizard创建一个Win32 Dynamic-Link Library工程,然后定义一个简单的C++类CInDLL.由于该类会被工程之外的文件所引用,所以需要对这个类进行引出。因为只有引出后所生成的DLL中才带有供足够的信息以在连接和运行时被正确引入到进程空间中。有两种方法可以引出类,使用__declspec(dllexport)定义和使用定义文件。

      下面先讲使用__declspec(dllexport)的方法:将类定义改为:class __declspec(dllexport) CInDLL 就可以了。 这样产生的工程在编译时是正确的但是在使用时会产生错误,因为你包含的头文件中也是使用__declspec(dllexport),而使用这个DLL的工程中并没有引出这个类,而是需要引入这个类)在使用时需要将类定义改为class __declspec(dllimport) CInDLL就可以了。

      使用定义文件可以有效的避免这个问题, 这种方法是利用宏定义在不同的地方产生不同的编译代码:

      在头文件中加入如下的代码:

      #ifndef ClassInDLL_H

          #define ClassInDLL_H

         #ifdef _CLASSINDLL

      #define CLASSINDLL_CLASS_DECL __declspec(dllexport)

      #else

      #define CLASSINDLL_CLASS_DECL __declspec(dllimport)

      #endif

      #endif // ClassInDLL_H

      //将class __declspec(dllexport) CInDLL改为

    class CLASSINDLL_CLASS_DECL CInDLL

      {

      CInDLL()

      ……

      }

      在实现这个类的CPP文件的顶部加入#define _CLASSINDLL语句,然后include头文件。

      #define _CLASSINDLL

         #include "CInDLL.h"

         CInDLL::CInDLL(){}……

      这样一来在使用这个类时就可以不做任何改动了。

    在使用这个类的工程中添加这个类的头文件,并设置或者动态链接.lib文件。

    linux C++ 共享库导出类

    1.共享库的对外接口函数的声明必须加上extern “C”。

    2.使用共享库对话接口函数生成的对象指针时在该对象未被释放之前不能关闭共享库句柄,否则会出现segmentation fault错误。

    以下是一个插件式设计的示例:

    1、主执行程序:main.cpp

    #include

    #include

    #include "SMSGamePlugin.h"

    int main(int argc, char** argv)

    {

            void *GameLib = dlopen("./Flower.so", RTLD_LAZY);

            const char *dlError = dlerror();

             if (dlError)

            {

                   < "dlopen error!" << dlError <<

                    return(-1);

            }

            CSMSGamePlugin *(*pGetGameObject)(void);

            pGetGameObject = (CSMSGamePlugin *(*)(void))dlsym(GameLib, "GetGameObject");

            dlError = dlerror();

            if (dlError)

            {

                   < "dlsym error!" << dlError <<

                    return(-1);

            }

            CSMSGamePlugin *pGame = (*pGetGameObject)();

            pGame->Initialize();

            pGame->Load();

            pGame->Handle();

            delete *pGame;

            dlclose(GameLib);

    }

    2、公用基类部分:SMSGamePlugin.h

    #ifndef __SMSGamePlugin_h__

    #define __SMSGamePlugin_h

    class CSMSGamePlugin

    {

    public:

            virtual int Initialize(void) = 0;

            virtual int Load(void) = 0;

            virtual int Handle(void) = 0;

    };

    #endif

    编译:g++ -rdynamic -ldl -s -o Test main.cpp

    3、共享库部分:

    共享库头文件:Flower.h

    #ifndef __Flower_h__

    #define __Flower_h__

    #include "SMSGamePlugin.h"

    extern "C" CSMSGamePlugin *GetGameObject(void);

    class CFlower: public CSMSGamePlugin

    {

    public:

            virtual int Initialize(void);

            virtual int Load(void);

            virtual int Handle(void);

    };

    #endif

    4、共享库实现文件:Flower.cpp

    #include

    #include "Flower.h"

    CSMSGamePlugin *GetGameObject(void)

    {

            return(new CFlower());

    }

    int CFlower::Initialize(void)

    {

           < "Initialize()" <<

            return(0);

    }

    int CFlower::Load(void)

    {

           < "Load()" <<

            return(0);

    }

    int CFlower::Handle(void)

    {

           < "Handle()" <<

            return(0);

    }

  • 相关阅读:
    多图详解!10大高性能开发核心技术(转发)
    从 Spring Cloud 看一个微服务框架的「五脏六腑」
    eclipse中的springBoot项目 执行maven build 和maven install 报错
    Mysql怎么删除某表中的一条数据
    eclipse 中需要配置jdk、需要配置jre吗? 以及安装eclipse后需要做的一些配置
    IntelliJ IDEA 2019.2最新版本免费激活码(亲测可用)
    在springBoot项目配置项目的访问路径的时候 server.context-path不起作用的原因
    共享类型的基站概念
    oracle创建索引
    ORACLE中的DBLINK概念及使用DBLINK对远程数据库的连接
  • 原文地址:https://www.cnblogs.com/imystr/p/4077825.html
Copyright © 2011-2022 走看看