Как переопределить виртуальный метод C ++ (не в классе интерфейса) в C # через C ++ / CLI - PullRequest
1 голос
/ 23 июня 2011

Для справки, этот вопрос касается доступа к C ++ NaturalPoint Camera SDK через C #.

Я пытаюсь передать реализацию виртуального метода из C ++ в C #. Проблема, с которой я сталкиваюсь, заключается в том, что виртуальный метод C ++ не находится в классе интерфейса, и я не могу это изменить. Вот объявление класса:

class CLAPI cCameraListener
{
public:
    cCameraListener()  {};
    ~cCameraListener() {};

    virtual void FrameAvailable();
    virtual void FrameOverflow();
    virtual void ButtonPressed();
};

CLAPI определяется как:

#define CLAPI __declspec(dllexport)

Я не могу наследовать от класса cCameraListener в классе ref, поскольку он не является интерфейсным классом и не нашел способа представить виртуальные методы управляемому классу. Мне также нужно иметь возможность зарегистрировать слушателя, о котором я расскажу ниже.

Вот рабочая реализация C ++ для прослушивания кадров:

// process frames as they arrive
class FrameListener: public cCameraListener
{
public:
  Camera *myCamera;
  FrameListener(Camera *cameraPtr)
  {
    myCamera = cameraPtr;
  };

  void FrameAvailable()
  {
    Frame *thisFrame = myCamera->GetFrame();

    // do something with the frame here

    thisFrame->Release();
  };
};

int _tmain(int argc, _TCHAR* argv[])
{
  // startup camera
  CameraManager::X().WaitForInitialization();
  Camera *camera = CameraManager::X().GetCamera();
  if(camera==0)
  {
      // print an error
      return 1;
  }

  // set camera properties
  camera->SendEmptyFrames(false);
  camera->SendInvalidFrames(false);
  camera->SetVideoType(SegmentMode);

  // setup frame listener
  FrameListener *myListener = new FrameListener(camera);
  camera->AttachListener(myListener);

  // start the camera
  camera->Start();

  // while loop holding thread

  // clean up
  camera->Release();
  CameraManager::X().Shutdown();

  return 0;
}

Вот некоторые из существующих кодов оболочки C ++ / CLI: Ссылка: https://code.google.com/p/npcamerasdkdotnet/

public ref class MCamera{
public:

  MCamera(Camera * camera){
    this->camera = camera;

  }
  ~MCamera(){
    delete this->camera;
  }

  void        Start(){camera->Start();} 

  void        SetExposure(int Value){camera->SetExposure(Value);}          
  void        SetThreshold(int Value){camera->SetThreshold(Value);}        
  void        SetIntensity(int Value){camera->SetIntensity(Value);}

  // TODO - WRAP THESE METHODS
  //void AttachListener(cCameraListener * Listener);
  //void RemoveListener(cCameraListener * Listener);

  // other wrapped methods here...

private:
  Camera * camera;
};

Обратите внимание, что в классе-оболочке MCamera необходимо реализовать метод AttachListener, для которого требуется указатель на класс cCameraListener, о котором говорилось выше.

Любые предложения будут оценены! Спасибо!

1 Ответ

2 голосов
/ 23 июня 2011

Решение не так сложно, вам нужно заключить слушателя в класс управления примерно так:


class CameraListenerImp;</p>

<p>/**
 * Managed Version of the listener which will be used by managed clients
 */
public ref class ManagedCameraListener abstract 
{
public:
        ManagedCameraListener();</p>

<pre><code>    virtual void FrameAvailable() abstract;
    virtual void FrameOverflow() abstract;
    virtual void ButtonPressed() abstract;

    ~ManagedCameraListener();

    CameraListenerImp* GetUnManagedListener()
    {
        return _unmanagedListener;
    }

private: CameraListenerImp * _unmanagedListener;};

// Неуправляемый класс-обработчик управляемого слушателя CameraListenerImp: public cCameraListener {public: CameraListenerImp (ManagedCameraListener ^ in) {theClass = in;} virtual void FrameAvailable () {theClass-> FrameAvailable ();} virtual void FrameOverflow () {theClass-> FrameOverflow ();} virtual void ButtonPressed () {theClass-> ButtonPressed ();} private: gcroot theClass;};

///////////////////////////////////////////////////////////////////////// // ManagedCameraListener imp ManagedCameraListener :: ManagedCameraListener () {_unmanagedListener = new CameraListenerImp (this);}

ManagedCameraListener :: ~ ManagedCameraListener () {delete _unmanagedListener;} /////////////////////////////////////////////////////////////// // ManagedCameraListener imp end

public ref class MCamera {public: MCamera (Camera * camera) {this-> camera = camera;} ~ MCamera () {удалить эту-> камеру;}

    void AttachListener( ManagedCameraListener^ listener )
    {
            // call unmanaged version of the AttachListener
            this->camera->AttachListener( listener->GetUnManagedListener() );
    }

    void RemoveListener( ManagedCameraListener^ listener )
    {
            // call unmanaged version of the RemoveListener
            this->camera->RemoveListener( listener->GetUnManagedListener() );
    }

личное: камера * камера;};

/ ** * Управляемая реализация * / public ref class MyOwnManagedCameraListener: public ManagedCameraListener {public: virtual void FrameAvailable () override {/ сделать что-то сложное /} virtual voidFrameOverflow () переопределить {/ сделать что-то сложное /} виртуальный void ButtonPressed () переопределить {/ сделать что-то сложное * /}};

int main (массив ^ аргументы) {MCamera ^ cam = gcnew MCamera (камера);MyOwnManagedCameraListener ^ listener = gcnew MyOwnManagedCameraListener ();

cam-> AttachListener (listener);cam-> RemoveListener (слушатель);вернуть 0;

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...