DLL中获取类封装

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

相关文章
相关标签/搜索