如何通过C ++ / CLI在C#中覆盖C ++虚拟方法(不在接口类中)

时间:2011-06-23 03:04:52

标签: c# c++-cli

作为参考,这个问题涉及通过C#访问C ++ NaturalPoint Camera SDK。

我试图将虚拟方法的实现从C ++传递给C#。我遇到的麻烦是C ++虚拟方法不在接口类中,我无法改变它。这是类声明:

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

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

CLAPI定义为:

#define CLAPI __declspec(dllexport)

我不能从refc类中的cCameraListener类继承,因为它不是接口类,并且没有提出任何方法将虚拟方法公开给托管类。我还需要能够注册我在下面谈到的听众。

以下是用于监听帧的工作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 个答案:

答案 0 :(得分:2)

解决方案并不是那么难,你需要将管理类中的监听器包装成类似的东西:


class CameraListenerImp;

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

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

    ~ManagedCameraListener();

    CameraListenerImp* GetUnManagedListener()
    {
        return _unmanagedListener;
    }

private: CameraListenerImp* _unmanagedListener; };

// Unmanaged to managed listener wraper class 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 < ManagedCameraListener^ > 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() { delete this->camera; }

    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() );
    }

private: Camera * camera; };

/** * Managed implementation */ public ref class MyOwnManagedCameraListener : public ManagedCameraListener { public: virtual void FrameAvailable() override { / do something hard / } virtual void FrameOverflow() override { / do something hard / } virtual void ButtonPressed() override { / do something hard */ } };

int main(array ^args) { MCamera^ cam = gcnew MCamera( camera ); MyOwnManagedCameraListener^ listener = gcnew MyOwnManagedCameraListener();

cam->AttachListener( listener ); cam->RemoveListener( listener ); return 0;

}