使用C ++中的dlsym加载共享对象函数

时间:2016-12-27 16:10:59

标签: c++ c dlopen dlsym

我试图从我安装的共享对象(.so)库中加载两个函数,但是当我编译我的代码时,当我尝试使用这些函数时会遇到一些错误,这里是'我的代码:

void G729ToPcmFilter::AudioChunkIn(AudioChunkRef& inputAudioChunk){

    std::string s = std::to_string(inputAudioChunk->GetNumBytes());
    LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn Size => " + s));

    typedef struct bcg729DecoderChannelContextStruct_struct bcg729DecoderChannelContextStruct;
    void *handle;
    bcg729DecoderChannelContextStruct (*initer)(bcg729DecoderChannelContextStruct);
    void (*decoder)(void);
    char* error;
    handle = dlopen ("libbcg729.so", RTLD_LAZY);
    if (!handle) {
            LOG4CXX_ERROR(LOG.rootLog, CStdString("Couldn't load Bcg729 plugin"));
        }
    else {
            *(void **) (&initer) = dlsym(handle,"initBcg729DecoderChannel");
            *(void **) (&decoder) = dlsym(handle,"bcg729Decoder");
            if ((error = dlerror()) != NULL)  {
                std::string str(error);
                LOG4CXX_ERROR(LOG.rootLog, CStdString("Couldn't load Bcg729 plugin's functions => "+str));
            } else {
                const char* inputBuffer = reinterpret_cast<const char*>((unsigned char*)inputAudioChunk->m_pBuffer);
                char *ret = (char*)malloc(10);
                memcpy(ret, inputBuffer, 10);
                char* firstFragment = ret;
                ret = (char*)malloc(10);
                memcpy(ret, inputBuffer+10, 10);
                char* secondFragment = ret;

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn buffer separated into two 10 bit buffers"));

                int16_t outputBuffer[80]; /* output buffer: the reconstructed signal */ 
                int16_t outputBuffer1[80]; /* output buffer: the reconstructed signal */ 
                uint8_t bitStream[10]; /* binary input for the decoder */

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn Buffers Created"));

                bcg729DecoderChannelContextStruct *decoderChannelContext = (*initer)();

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn Decoder Initialized"));

                for(int i=0; i < 10 ; i++){
                    bitStream[i] = (uint8_t)atoi(&firstFragment[i]);
                }

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn First BitStream Created"));

                (*decoder)(decoderChannelContext, bitStream, 1, outputBuffer);

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn First Stream Decoding DONE"));

                for(int i=0; i < 10 ; i++){
                    bitStream[i] = (uint8_t)atoi(&secondFragment[i]);
                }

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn Second BitStream Created"));

                (*decoder)(decoderChannelContext, bitStream, 0, outputBuffer1);

                LOG4CXX_ERROR(LOG.rootLog, CStdString("G729 AudioChunkIn Second Stream Decoding DONE"));

                m_outputAudioChunk.reset(new AudioChunk());
                AudioChunkDetails chunkDetails = *inputAudioChunk->GetDetails();
                chunkDetails.m_rtpPayloadType = -1;
                chunkDetails.m_encoding = PcmAudio;
                chunkDetails.m_numBytes = 160;
                short* outputBufferFinal = (short*)m_outputAudioChunk->CreateBuffer(chunkDetails);
                for(int i = 0; i < 80; i++){
                    outputBufferFinal[i] = outputBuffer[i];
                    outputBufferFinal[i+80] = outputBuffer1[1];
                }

            }
    }
}

我知道,编译时出现以下错误,我确定通过了.so库中声明的参数,我使用了:

G729Codec.cpp: In member function ‘virtual void G729ToPcmFilter::AudioChunkIn(AudioChunkRef&)’:
G729Codec.cpp:173:74: error: too few arguments to function
     bcg729DecoderChannelContextStruct *decoderChannelContext = (*initer)();
                                                                          ^
G729Codec.cpp:183:65: error: too many arguments to function
     (*decoder)(decoderChannelContext, bitStream, 1, outputBuffer);
                                                                 ^
G729Codec.cpp:193:66: error: too many arguments to function
     (*decoder)(decoderChannelContext, bitStream, 0, outputBuffer1);

在libbcg729.so库的标题上,函数声明如下:

BCG729_VISIBILITY bcg729DecoderChannelContextStruct *initBcg729DecoderChannel();
BCG729_VISIBILITY void bcg729Decoder(bcg729DecoderChannelContextStruct *decoderChannelContext, uint8_t bitStream[], uint8_t frameErasureFlag, int16_t signal[]);

我无法弄清楚我做错了什么,有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

它看起来像是函数指针的声明:

  

bcg729DecoderChannelContextStruct(* initer)(bcg729DecoderChannelContextStruct);
  void(* decoder)(void);

错了,我想他们应该是这样的:

  

bcg729DecoderChannelContextStruct *(* initer)();
  void bcg729Decoder(...请参阅bcg729库函数签名的bcg729库头文件)

您可能还想检查是否需要将这些声明指定为extern“C”,因为bcg729库是用C语言编写的,而不是C ++。