转载地址:https://www.gkbc8.com/thread-13546-1-1.html
set_framegrabber_callback函数要求传递一个回调函数地址。
第一次使用,真不知道如何传递。
这里分享给大家方法。代码来自网络的C#版本。
创建c#窗口工程,并进行halcon相关的配制。之后是创建一个回调函数,获取此回调函数地址,并传递给set_framegrabber_callback使用。
public int MyCallbackFunction(IntPtr handle, IntPtr context, IntPtr user_context)
关键代码为
HalconDotNet.HalconAPI.HFramegrabberCallback delegateCallback;//定义一个halcon 的回调函数变量并赋值
delegateCallback= MyCallbackFunction;
此回调函数变量地址通过下面获取
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(delegateCallback);//取回调函数的地址
ptr变量就是我们想要的回调函数地址了,可以进行传递使用。
HOperatorSet.SetFramegrabberCallback(hv_AcqHandle,"LineStatus", ptr, ptr1);
ptr1为传递的另一个参数,查看下面源代码。
注意
using HalconDotNet;
using System.Runtime.InteropServices;
两名的引用
下面是源代码,可参考用于自己项目中
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public HTuple hv_AcqHandle = null;//定义相机句柄
public HObject img = null;//定义图像变量
HalconDotNet.HalconAPI.HFramegrabberCallback delegateCallback;//定义一个委托
private void Form1_Load(object sender, EventArgs e)//窗体加载的时候委托绑定及开启相机等操作
{
//给委托绑定
delegateCallback = MyCallbackFunction;
//开启相机
HOperatorSet.OpenFramegrabber("GigEVision2", 0, 0, 0, 0, 0, 0, "progressive",
-1, "default", -1, "false", "default", "38af2918ce35_DahuaTechnology2EDa_A7A20MG9jsn63S",
0, -1, out hv_AcqHandle);
//下面开启硬触发
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "TriggerMode", "On");
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "TriggerSource", "Line1");
//下面设置连续采集,上升沿触发,曝光模式等
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "AcquisitionMode", "Continuous");
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "TriggerSelector", "FrameStart");
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "TriggerActivation", "RisingEdge");
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "ExposureMode", "Timed");
//设置曝光时间
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "ExposureTime", 80000.0);
//下面为设置用不超时
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "grab_timeout", -1);
}
private int test = 1;//随便定义的一个变量,后面会取其地址带入回调函数的user_context
public int MyCallbackFunction(IntPtr handle, IntPtr context, IntPtr user_context)//回调函数
{
try
{
HOperatorSet.GrabImage(out img, hv_AcqHandle);
if (this.hWindowControl1.InvokeRequired)//线程亲和性判定
{
this.Invoke(new MethodInvoker(() => { HOperatorSet.DispObj(img, this.hWindowControl1.HalconWindow); img.Dispose(); }));//把图像显示出来(这里是委托方式显示)
}
else
{
HOperatorSet.DispObj(img, this.hWindowControl1.HalconWindow);//把图像显示出来
img.Dispose();
}
return 0;
}
catch (Exception ex)
{
// MessageBox.Show(ex.Message);//显示错误
return -1;
}
}
private void btnReg_Click(object sender, EventArgs e)//这里注册回调
{
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(delegateCallback);//取回调函数的地址
IntPtr ptr1 = GCHandle.Alloc(test, GCHandleType.Pinned).AddrOfPinnedObject();//取test变量的地址
//因为大华的相机不支持"transfer_end"等模式,只能用 "LineStatus"作演示
HOperatorSet.SetFramegrabberCallback(hv_AcqHandle, "LineStatus", ptr, ptr1);//注册回调函数
}
private void btnGetPara_Click(object sender, EventArgs e)//返回支持available_callback_types的列表参数
{
HTuple Value=null;
//下面返回支持回调的列表
HOperatorSet.GetFramegrabberParam(hv_AcqHandle,"available_callback_types",out Value);
int l = Value.Length;
for(long i=0;i<l;i++)
{
this.listBox1.Items.Add(Value[i].S);
}
}
private void btnCloseCamera_Click(object sender, EventArgs e)//关闭相机
{
if (hv_AcqHandle == null) return;
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
}
//-------以下是循环方式采集图像--------------------------------------
private bool exitloop = false;//推出循环命令
private void btnLoop_Click(object sender, EventArgs e)//采用循环的方式去取图
{
exitloop = false;
btnExitLoop.Focus();
System.Threading.Thread.Sleep(100);
while(exitloop==false)
{
Application.DoEvents();
try
{
HOperatorSet.GrabImage(out img, hv_AcqHandle);
HOperatorSet.DispObj(img, this.hWindowControl1.HalconWindow);
Application.DoEvents();
}
catch (Exception)
{
Application.DoEvents();
continue;
//throw;
}
}
}
private void btnExitLoop_Click(object sender, EventArgs e)//退出循环
{
exitloop = true;
}
}
}