轉載地址: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;
}
}
}