2016-09-11 2 views
1

In einem Android-Projekt habe ich eine ziemlich chaotische Vererbungssituation, die ich nicht vollständig verstehe. Dies ist der Fehler, den ich Kompilieren erhalten:C++ - Implementierung der abstrakten Methode nicht erfüllt

proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:4458:51: error: cannot allocate an object of abstract type 'android::MediaRecorder' 
     m_MediaRecorderClient = new MediaRecorder(); 
               ^
In file included from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.h:101:0, 
       from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:199: 
frameworks/av/include/media/mediarecorder.h:245:7: note: because the following virtual functions are pure within 'android::MediaRecorder': 
class MediaRecorder : public BnMediaRecorderClient, 
    ^
In file included from frameworks/av/include/media/mediarecorder.h:30:0, 
       from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.h:101, 
       from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:199: 
frameworks/av/include/media/IMediaRecorderClient.h:32:18: note:  virtual void android::IMediaRecorderClient::readAudio() 
    virtual void readAudio() = 0; 

Dies ist die Klasse MediaRecorder von mediarecorder.h

............ 
....... 
#include <media/IMediaRecorderClient.h> 
....... 
........... 

class MediaRecorder : public BnMediaRecorderClient, 
         public virtual IMediaDeathNotifier 
{ 
public: 
    MediaRecorder(); 
    ~MediaRecorder(); 

    void  died(); 
    status_t initCheck(); 
    status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy); 
    status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface); 
    status_t setVideoSource(int vs); 
    status_t setAudioSource(int as); 
    status_t setOutputFormat(int of); 
    status_t setVideoEncoder(int ve); 
    status_t setAudioEncoder(int ae); 
    status_t setOutputFile(const char* path); 
    status_t setOutputFile(int fd, int64_t offset, int64_t length); 
    status_t setVideoSize(int width, int height); 
    status_t setVideoFrameRate(int frames_per_second); 
    status_t setParameters(const String8& params); 
    status_t setListener(const sp<MediaRecorderListener>& listener); 
    status_t setClientName(const String16& clientName); 
    status_t prepare(); 
    status_t getMaxAmplitude(int* max); 
    status_t start(); 
    status_t stop(); 
    status_t reset(); 
    status_t init(); 
    status_t close(); 
    status_t release(); 
    void  notify(int msg, int ext1, int ext2); 
    sp<IGraphicBufferProducer>  querySurfaceMediaSourceFromMediaServer(); 

#ifdef MTK_AOSP_ENHANCEMENT 
    status_t setParametersExtra(const String8& params); 
#endif 

private: 
    void     doCleanUp(); 
    status_t    doReset(); 

    sp<IMediaRecorder>   mMediaRecorder; 
    sp<MediaRecorderListener> mListener; 

    // Reference to IGraphicBufferProducer 
    // for encoding GL Frames. That is useful only when the 
    // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER 
    sp<IGraphicBufferProducer> mSurfaceMediaSource; 

    media_recorder_states  mCurrentState; 
    bool      mIsAudioSourceSet; 
    bool      mIsVideoSourceSet; 
    bool      mIsAudioEncoderSet; 
    bool      mIsVideoEncoderSet; 
    bool      mIsOutputFileSet; 
    Mutex      mLock; 
    Mutex      mNotifyLock; 
}; 

Diese IMediaRecorderClient.h ist

#include <utils/RefBase.h> 
#include <binder/IInterface.h> 
#include <binder/Parcel.h> 

namespace android { 

class IMediaRecorderClient: public IInterface 
{ 
public: 
    DECLARE_META_INTERFACE(MediaRecorderClient); 

    virtual void notify(int msg, int ext1, int ext2) = 0; 
    virtual void readAudio() = 0; 
}; 

// ---------------------------------------------------------------------------- 

class BnMediaRecorderClient: public BnInterface<IMediaRecorderClient> 
{ 
public: 
    virtual status_t onTransact(uint32_t code, 
            const Parcel& data, 
            Parcel* reply, 
            uint32_t flags = 0); 
}; 

}; 

Und dies ist ein Auszug aus IMediaRecorderClient.cpp, das scheint mir die abstrakte Methode virtual void readAudio()

zu implementieren
#include <utils/RefBase.h> 
#include <binder/IInterface.h> 
#include <binder/Parcel.h> 

#include <media/IMediaRecorderClient.h> 

namespace android { 

enum { 
    NOTIFY = IBinder::FIRST_CALL_TRANSACTION, 
    READ_AUDIO, 
}; 

class BpMediaRecorderClient: public BpInterface<IMediaRecorderClient> 
{ 
public: 
    BpMediaRecorderClient(const sp<IBinder>& impl) 
     : BpInterface<IMediaRecorderClient>(impl) 
    { 
    } 

    virtual void notify(int msg, int ext1, int ext2) 
    { 
     Parcel data, reply; 
     data.writeInterfaceToken(IMediaRecorderClient::getInterfaceDescriptor()); 
     data.writeInt32(msg); 
     data.writeInt32(ext1); 
     data.writeInt32(ext2); 
     remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); 
    } 

    virtual void readAudio() 
    { 
     Parcel data, reply; 
     data.writeInterfaceToken(IMediaRecorderClient::getInterfaceDescriptor()); 
     remote()->transact(READ_AUDIO, data, &reply, IBinder::FLAG_ONEWAY); 
    } 
}; 

Wo liege ich falsch?

+1

TLDR: Der Compiler sagt Ihnen genau, was das Problem ist. –

+0

Was @ DieterLücking sagt, die Fehlermeldung ist 100% klar. Aber falls es Ihnen nicht klar ist, wird der BpMediaRecorderClient durch den fehlerhaften Code nicht instanziiert. Es instanziiert einen 'MediaRecorder'. –

+0

Danke Jungs, genau das habe ich befürchtet. Ich hatte gehofft, dass ein Mechanismus, den ich nicht bekommen konnte, das Problem lösen würde. Also, wenn ich MediaRecorder instantiieren würde, sollte ich readAudio definieren, richtig? – 4javier

Antwort

0

Der Compiler sagt Ihnen, dass in der folgenden Aussage von AudioCmdHandler.cpp:

m_MediaRecorderClient = new MediaRecorder(); 

es ist ein Versuch, die Klasse MediaRecorder, die ist eine abstrakte Klasse zu instanziiert. Eine abstrakte Klasse bedeutet, dass sie mindestens eine virtuelle Funktion hat, die überhaupt nicht definiert ist, und in Ihrem Fall ist es readAudio().

Wie kommt es?

Die Klassendefinition MediaRecorder, die Sie angezeigt haben, bietet keine readAudio(). Aber die Klasse erbt von BnMediaRecorderClient. Dieser liefert weder readAudio() noch erbt von einer Vorlage BnInterface<IMediaRecorderClient>.

Ich weiß nicht, wie genau die Template-Klasse BnInterface<...> definiert ist, aber ich denke, es ist ein CRTP ist, dass die Schnittstelle als Argument bereitgestellt erstreckt, so dass am Ende MediaRecorder indirekt von IMediaRecorderClient erben.

Und dieser definiert diese rein virtuelle Funktion:

virtual void readAudio() = 0; 

Wie es zu lösen?

Sie müssen diese Funktion bereitstellen und in MediaRecorder implementieren, um Objekte dieser Klasse instanziieren zu können.

+0

Dank dir auch. Frühere Antworten waren korrekt, über Ihren ist vollständiger. Ich werde es als akzeptiert markieren. – 4javier

+0

@ 4javier: Sie sollten wahrscheinlich "BpMediaRecorderClient" oder eine andere konkrete Klasse instanziieren, nicht mit der 'MediaRecord' Klasse. –

Verwandte Themen