做爲C++新手,在項目中寫一個動態加載的codec的程序,由於要考慮動態類的加載,因此對於dll文件進行了一些嘗試處理。函數
主要問題是dll文件的加載函數沒有提取class或是對象的接口,所以只能經過全局函數解決。ui
代碼以下:code
1, 定義codec的接口:對象
class ICodec
{
public:
virtual status_t open() = 0;
virtual void close() = 0;
virtual sp<Message> query() =0;
virtual status_t control() = 0;
virtual status_t process() = 0;
};繼承
定義這個接口的目的是使dll可以經過繼承ICodec接口,從而在調用者不知道dll中codec的具體細節的狀況下,向外提供codec的功能
接口
2. DLL的實現get
MyCodec gMyCodec;
status_t MyCodec::open( const sp<Message>& params)
{
cout<<"call MyCodec.open successfully"<<endl;
return OK;
}
void MyCodec::close()
{
cout<<"call MyCodec.close successfully"<<endl;
}
sp<Message> MyCodec::query()
{
cout<<"call MyCodec.query successfully"<<endl;
return NULL;
}
status_t MyCodec::control( ECmd eCmd, sp<Message>& params)
{
cout<<"call MyCodec.control successfully"<<endl;
return GENERAL_ERROR;
}
status_t MyCodec::process( const sp<Buffer>&src, BufferVecs& dst, uint32_t flags)
{
cout<<"call MyCodec.process successfully"<<endl;
return GENERAL_ERROR;
}
extern "C"
TXBASE_API ICodec* getCodec()
{
return &gMyCodec;
}it
利用最後的getCodec,傳出MyCodec的對象,而這個對象是派生自ICodec的,所以外部調用者能夠直接看成ICodec操做。io
3. 在外部調用時,封裝dll提供的功能ast
typedef ICodec* (*CODEC_GETTER)();
//class Dynamic: public ICodec
status_t DynamicCodec::open( const sp<Message>& params)
{
if (mDllCodec != NULL)
{
mDllCodec->open(params);
}
else
{
return NO_INIT;
}
}
void DynamicCodec::close()
{
if (mDllCodec != NULL)
{
mDllCodec->close();
}
else
{
return;
}
}
sp<Message> DynamicCodec::query()
{
if (mDllCodec != NULL)
{
return mDllCodec->query();
}
else
{
return NULL;
}
}
status_t DynamicCodec::control( ECmd eCmd, sp<Message>& params)
{
if (mDllCodec != NULL)
{
mDllCodec->control(eCmd, params);
}
else
{
return NO_INIT;
}
}
status_t DynamicCodec::process( const sp<Buffer>&src, BufferVecs& dst, uint32_t flags)
{
if (mDllCodec != NULL)
{
mDllCodec->process(src, dst, flags);
}
else
{
return NO_INIT;
}
}
status_t DynamicCodec::init(const char* dllPath)
{
mModule = LoadLibraryW(dllPath); //HINSTANCE mModule
if (NULL == mModule)
{
return NAME_NOT_FOUND;
}
CODEC_GETTER getter = (CODEC_GETTER)dl_findSymbol(mModule, "getCodec");
//class twl::ICodec * twl::getCodec(void)
if (NULL == getter)
{
DWORD word = GetLastError();
LOGE("failed to load function from dll, errorCode: %d", word);
return NAME_NOT_FOUND;
}
mDllCodec = (*getter)();
if (NULL == mDllCodec)
{
FreeLibrary(mModule);
return GENERAL_ERROR;
}
else
{
return OK;
}
}
void DynamicCodec::clear()
{
mDllCodec->close();
FreeLibrary(mModule);
}
經過Dynamic類的實例化,完成方法調用的傳遞,從而至關於利用dll中的類MyCodec。