做为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。