用C++面向?qū)ο蟮姆绞絼討B(tài)加載so的方法
這幾天在寫一個server,由于框架相同,僅僅是獲取數(shù)據(jù)源的地方有區(qū)別,所以,研究了一下如何使用面向?qū)ο蟮姆椒▉韯討B(tài)加載so。
主要思想就是:
1.通過一個函數(shù)能夠獲得一個基類的指針,這樣在調(diào)用基類的函數(shù)的時候,就能自動調(diào)用子類的實現(xiàn)了。
2.存儲so對象的指針應(yīng)該是外層類的一個static變量。
詳細還是看代碼吧:
1)首先定義一個公共的頭文件,里面存儲的基類的定義:(需要注意的就是,只要不是純虛函數(shù),那么就一定要有實現(xiàn);還有就是析構(gòu)函數(shù)需要為虛函數(shù))
so和主調(diào)程序都需要包含這個頭文件。
source_base.h
#ifndef _SOURCE_BASE_H_
#define _SOURCE_BASE_H_
#include <iostream>
using namespace std;
class CSourceBase;
/**
* @brief 獲取實例
*
* @param client new出的指針
*
* @return 0 succ
* else fail
*/
extern “C” int CreatObj(CSourceBase *& client);
class CSourceBase
{
public:
CSourceBase(){};
virtual ~CSourceBase(){};
public:
virtual int GetFriends(int iUin,char *data,int &iLen,int maxLen)
{
return 0;
}
};
#endif
2)我們來看so的實現(xiàn)
xy_source.h
#ifndef _XY_SOURCE_H_
#define _XY_SOURCE_H_
#include <iostream>
#include “sourcebase.h”
using namespace std;
class CXY_Source:public CSourceBase
{
public:
CXY_Source();
virtual ~CXY_Source();
{}
int GetFriends(int iUin,char *data,int &iLen,int maxLen);
};
#endif
xy_source.cpp
#include “xy_source.h”
int CreatObj(CSourceBase *& client)
{
client = new CXY_Source();
return 0;
}
CXY_Source::CXY_Source() { }
CXY_Source::~CXY_Source() { }
int CXY_Source::GetFriends(int iUin,char *data,int &iLen,int maxLen)
{
return 0;
}
3)調(diào)用者的實現(xiàn)
這里說明一下,因為這里想要對外封裝成透明的,所以,采用了如下的方式。
xy_client.h
#ifndef _XY_CLIENT_H_
#define _XY_CLIENT_H_
#include <iostream>
#include “sourcebase.h”
using namespace std;
typedef int (*FunPtr)(CSourceBase *& client);
class CXY_Client
{
public:
static void *SoObj;
public:
CXY_Client();
virtual ~CXY_Client();
//載入so
int Init(const char * soname);
int GetFriends(int iUin,char *data,int &iLen,int maxLen);
private:
CSourceBase *m_Client;
};
xy_client.cpp
#include “xy_client.h”
void* CXY_Client::SoObj=NULL;
CXY_Client::CXY_Client()
{
m_Client = NULL;
}
CXY_Client::~CXY_Client()
{
if(m_Client)
{
delete m_Client;
}
}
int CXY_Client::Init(const char * soname)
{
string strSoName;
if(soname==NULL)
{
strSoName = “../lib/xysource.so”;
}
else
{
strSoName = soname;
}
if(strSoName.size()==0)
{
strSoName = “../lib/xysource.so”;
}
if(CXY_Client::SoObj == NULL)
{
SoObj=dlopen((char*)strSoName.c_str(),RTLD_LAZY);
if(SoObj==NULL)
{
return -1;
}
}
if(m_Client==NULL)
{
FunPtr func;
func = (FunPtr)dlsym(SoObj, “CreatObj”);
int ret = (*func)(m_Client);
if(ret)
{
return -2;
}
}
return 0;
}
int CXY_Client::GetFriends(int iUin,char *data,int &iLen,int maxLen)
{
return m_Client->GetFriends(iUin,data,iLen,maxLen);
}
OK,到此為止代碼就結(jié)束了,大家可能會發(fā)現(xiàn)我沒有調(diào)用dlclose,這是因為static變量沒有必要來調(diào)用,在進程結(jié)束時會自動釋放句柄,當然如果需要有釋放的應(yīng)用場景的話,可以通過增加計數(shù)來實現(xiàn)。
另外由于上面的這個實例是從項目中摳出來的,所以并不能直接編譯,還望大家見諒。
但是在這里可以下載到一個簡單的可編譯實例,可以用來作為實現(xiàn)so動態(tài)加載編程的第一步~~
以上就是小編為大家?guī)淼挠肅++面向?qū)ο蟮姆绞絼討B(tài)加載so的方法全部內(nèi)容了,希望大家多多支持腳本之家~
相關(guān)文章
C++數(shù)據(jù)結(jié)構(gòu)之單鏈表
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個個結(jié)點鏈結(jié)成的。結(jié)點包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來存儲數(shù)據(jù)元素的信息,指針域用來存儲下一個結(jié)點的地址,更詳細內(nèi)容請需要的小伙伴參考下面文章內(nèi)容2022-01-01
深入C/C++浮點數(shù)在內(nèi)存中的存儲方式詳解
本篇文章是對C/C++浮點數(shù)在內(nèi)存中的存儲方式進行了詳細的分析介紹,需要的朋友參考下2013-05-05
C語言入門篇--sizeof與strlen基礎(chǔ)理論
本篇文章是c語言基礎(chǔ)篇,主要為大家介紹了C語言的sizeof與strlen的基本理論知識,希望可以幫助大家快速入門c語言的世界,更好的理解c語言2021-08-08

