Halcon版本:18.11
文档名称:programmers_guide.pdf
目录
Chapter 10 Creating Applications With HALCON/.NET
10.5.2 Calling HALCON Operators
10.5.3 From Declaration to Finalization
Chapter 10 Creating Applications With HALCON/.NET
10.5.2 Calling HALCON Operators
static void HOperatorSet.GrabImage(out HObject image, HTuple acqHandle)
void HImage.GrabImage(HFramegrabber acqHandle)
HImage HFramegrabber.GrabImage()
image(output_object)....................image~HImage(byte/uint2)
acqHandle(intput_control)...............framegrabber~HFramegrabber/HTuple(IntPtr)
如上所示,我们可以使用三个类调用GrabImage函数。当通过Halcon直接导出C#代码时,主要使用HOperatorSet类调用。如果不使用直接导出代码的方式,而是直接在C#环境下编写Halcon代码,官方建议使用其它类去调用函数。
10.5.3 From Declaration to Finalization
HImage image1;
在这种状态下,不能使用变量调用任何函数;根据编程语言的不同,甚至可能无法将其用作输出参数(例如,在VisualBasic2005中)。但是,可以将HImage对象分配给该变量,例如,函数的返回值:
image1 = Framegrabber.GrabImage();
我们可以在声明该变量的时候进行初始化,如下所示:
HImage Image2 = Framegrabber.GrabImage();
HImage Image3 = null;
我们可以使用IsInitialized函数来判断该变量是否初始化
10.5.3.1 Constructors
与上述不同,下面的声明方式调用了HImage类的空构造函数,创建了一个未初始化的类实例:
HImage Image4 = new HImage();
此类实例可用于调用“类似构造函数”的运算符,如GrabImage,它使用抓取的图像初始化Image4:
Image4.GrabImage(Framegrabber);
除了空的构造函数之外,大多数HALCON/.NET类都提供一个或多个基于HALCON运算符初始化所创建对象的构造函数。例如,HImage提供了一个基于操作符ReadImage的构造函数:
HImage Image5 = new HImage("fuse");//“fuse”可以替换为图片路径名
10.5.3.2 Finalizers
static void HOperatorSet.CloseFramegrabber (HTuple acqHandle)
void HFramegrabber.CloseFramegrabber ()
如果您想用不同的参数重新打开连接,甚至不需要调用这样的运算符,因为这是自动完成的。
当使用HFramegrabber等常规类时,请不要通过HOperatorSet调用Close或Clear运算符。
10.5.3.3 Garbage Collection
- 手动调用垃圾回收器,在计时器事件中调用如下代码:
private void Timer_Tick(object sender, System.EventArgs e)
{
Action();
GC.Collect();
GC.WaitForPendingFinalizers();
}
在托管C++应用程序中调用垃圾回收器的代码是:
GC::Collect();
GC::WaitForPendingFinalizers();
- 通过调用Dispose方法手动处理单个对象:
HImage Image = new HImage("fuse");
...
Image.Dispose();
除了减少内存消耗外,手动处理对象的另一个原因是释放资源,例如,关闭与图像采集设备或串行接口的连接。
如果要以确定的方式释放引用的资源,则还需要释放包含句柄的HTuple实例。
请注意,HALCON操作符总是为输出参数和返回值创建一个新的对象实例(与10.5.3.1 中的Image4.GrabImage(Framegrabber)不同)。如果变量已经初始化,则其旧内容(以及为其分配的内存)仍然存在,直到垃圾回收器将其删除。如果要手动删除它,则必须在为其分配对象之前调用Dispose。
根据上述内容,VS2017与Halcon18.11联合编程如下:
private void button1_Click(object sender, EventArgs e)
{
HImage image1; //未赋值的局部变量,未引用任何对象实例。不能调用任何halcon函数,否则编译失败
HImage image2 = null; //赋值的局部变量,未引用任何对象实例。可以调用halcon函数,且编译成功。但运行会失败,因为未引用任何对象实例
HImage image3 = new HImage(); //引用了对象实例,但未初始化,Key = 0x0000000000000000
HImage image4 = new HImage("1.bmp"); //引用了对象实例,并初始化,Key = 0x0000023cb701c6b0
if (image1.IsInitialized())//编译失败
{
int i = 0;
}
if (image2.IsInitialized())//运行失败
{
int i = 0;
}
if (image3.IsInitialized())//未初始化,函数返回false
{
int i = 0;
}
if (image4.IsInitialized())//初始化,函数返回true
{
int i = 0;
}
}
HObject类型的变量可以使用GenEmptyObj函数初始化
HRegion类型的变量可以使用GenEmptyRegion函数初始化
综上所述:
1、当不再使用HObject(HImage、HRegion等图标变量)类型的变量时,一定要手动调用Dispose函数将其释放,否则将造成内存泄露;
2、如果一个HObject类型的变量已经被初始化,那么必须在给它分配新的对象之前手动调用Dispose函数将其旧对象释放,否则将造成内存泄露;
3、image1 = image2,相当于浅拷贝。image1 = image2.CopyObj(1,-1)相当于深拷贝;
4、Halcon17.12版本中HTuple类型不包括Dispose函数,Halcon18.11版本中加入了Dispose函数;