作为参考,这个问题涉及通过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类的指针。
任何建议将不胜感激!谢谢!
答案 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;
}