先说结论:海康相机在多相机实例时,不需要每个相机都注册回调函数,注册一次,通过回调函数的pUser指针可以获取到是哪个相机的回调。因此单相机或者不封装的朋友反而不会碰到这种错。
我做相机已经习惯性思维了,不管什么牌子相机都是实例化-注册回调-打开-设置UserSet1-开启码流-硬触发/软触发-关流-销毁实例。所以就按照basler的自己开了个类。没想到直接在回调报了个错,说是Invoke类型的已垃圾回收委托进行了回调,查百度都是牛头不对马嘴。
因为我已经实验过单相机回调没问题了,所以多相机就直接复制了多个回调。回调改成打印一句话也还是报同样错,因此相机回调还没传到外面的实例,就已经崩了,多半就是封装的问题。看了海康的多相机demo,发现一个问题,相机有4个实例,回调函数只有一个实例,4个相机注册了四次回调,但都是同一个回调实例。
例如:
private MyCamera[] m_pMyCamera;//相机对象
MyCamera.cbOutputExdelegate cbImage;//回调对象
Form()//窗体构造里实例化这个回调对象,但是相机是数组结构
{
InitializeComponent();
cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack);
}
public Init()
{
for(int i = 0;i<count;i++)
{
m_pMyCamera[i] = new MyCamera();//初始化,怎么写不重要
m_pMyCamera[i].MV_CC_CreateDevice_Net(ref device);
m_pMyCamera[i].MV_CC_OpenDevice_Net();
m_pMyCamera[i].MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i);//重点是这句话
}
}
private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
{
int nIndex=(int) pUser;//这里就是刚才注册的(IntPtr)i的pUser
// ch:抓取的帧数 | en:Aquired Frame Number
++m_nFrames[nIndex];
}
最后一个RegisterImageCallBack就说明了问题,我相信还是有朋友和我一样粗心的,不看pUser就直接回调了,我仿照demo改了一下类,就发现没报错了,CallBack也能正常出来了,回调出来的时候记得把pData存到一个数组里,然后开个线程去转Bitmap,也容易出问题,不过耐心点改改就没事了。