Linux下的共享库的开发

本文深入探讨了Linux环境下动态库的开发与使用,包括如何通过dl系列接口进行动态库的加载、符号解析及错误处理。并通过实例展示了主程序如何与动态库进行交互,实现功能的灵活扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    Linux共享库技术是一项很激动人心的技术,它充分提供了程序的动态扩展能力,能够方便的进行Linux下程序的插件式开发。而且在运行过程中,如果需求有更改,只需要更新相应的共享库,从而能很方便的实现功能的无缝切换,极大的提供了程序的动态扩展能力。下面将说明动态库的开发方式。

   1、支持动态库的主程序的开发:

           在使用dl系列接口时,需要包含头文件  #include <dlfcn.h>

           a).调用dlopen函数打开到共享库的操作句柄;

                 函数接口为: void *dlopen(const char *filename, int flag);  filename为使用的动态库的文件所在的路径,一般扩展名为.so;

           b).调用dlsym函数从共享库符号中获取对应的操作接口和操作对象数据;

                 函数接口为: void *dlsym(void *handle, const char *symbol); symbol为查找的符号,handle为上面打开的共享库操作句柄;返回结果为共享库中实现的接口;

           c).调用dlcose函数关闭共享库操作句柄:

                 函数接口为:  int dlclose(void *handle);     关闭打开的文件句柄;

           d).在上面的3个函数调用后,可以使用  char *dlerror(void);   函数去查询共享库操作中出现的错误;


     2、动态库的开发:

            共享库中只需要实现主程序中需要操作的接口即可,主要需要注意以下的事项:

            a).共享库对外提供接口的头文件中必须使用   extern "C"   包含起来,否则执行时会出现segment fault;

            b).在共享库操作接口中打开的对象等资源必须在关闭共享库操作句柄之前释放,否则会出现segment fault;

            c).共享库的链接只需要在gcc中增加 -shared  选项;


     下面是一个例子:

主执行程序: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)
        {
                std::cout << "dlopen error!" << dlError << std::endl;
                return(-1);
        }
        CSMSGamePlugin *(*pGetGameObject)(void);
        pGetGameObject = (CSMSGamePlugin *(*)(void))dlsym(GameLib, "GetGameObject");
        dlError = dlerror();
        if (dlError)
        {
                std::cout << "dlsym error!" << dlError << std::endl;
                return(-1);
        }
        CSMSGamePlugin *pGame = (*pGetGameObject)();
        pGame->Initialize();
        pGame->Load();
        pGame->Handle();
        delete *pGame;
        dlclose(GameLib);
}

公用基类部分: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

共享库部分:

共享库头文件: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

共享库实现文件:Flower.cpp
#include
#include "Flower.h"

CSMSGamePlugin *GetGameObject(void)
{
        return(new CFlower());
}

int CFlower::Initialize(void)
{
        std::cout << "Initialize()" << std::endl;
        return(0);
}

int CFlower::Load(void)
{
        std::cout << "Load()" << std::endl;
        return(0);
}

int CFlower::Handle(void)
{
        std::cout << "Handle()" << std::endl;
        return(0);
}

编译:
    g++ -c Flower.cpp
    g++ -shared -o Flower.so

注意:
如果不加extern "C"编译后运行时就会提示:
dlsym error!./Test: undefined symbol: GetGameObject


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值