【问题标题】:How to override a C++ virtual method (not in an interface class) in C# via C++/CLI如何通过 C++/CLI 在 C# 中覆盖 C++ 虚拟方法(不在接口类中)
【发布时间】:2011-06-23 03:04:52
【问题描述】:

作为参考,此问题涉及通过 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)

我不能从 ref 类中的 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 类的指针。

任何建议将不胜感激!谢谢!

【问题讨论】:

标签: c# c++-cli


【解决方案1】:

解决方案并不难,您需要将侦听器包装在管理类中,如下所示:


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;

}

【讨论】:

  • 这很好用,谢谢萨沙!我会将此链接传递给 NaturalPoint 论坛,我相信那里的人们也会从中受益。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 2011-05-21
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多