目录
1.C++项目引用HALCON依赖
1.1C++项目引用HALCON依赖
pro添加
# HALCON
#include
INCLUDEPATH += $$(HALCONROOT)/include
INCLUDEPATH += $$(HALCONROOT)/include/halconcpp
INCLUDEPATH += $$(HALCONROOT)/include/hdevengine
#libs
LIBS += -L$$(HALCONROOT)/lib/$$(HALCONARCH) -lhalcon -lhalconcpp -lhdevenginecpp
1.2添加HALCON头文件、命名空间
设置路径
#include "HalconCpp.h" #include "HDevEngineCpp.h" using namespace HalconCpp; using namespace HDevEngineCpp; |
2.流程介绍
2.1引擎引用说明
主要用得到的类:HDevEngine、HDevProgram、HDevProgramCall、HDevProcedure、HDevProcedureCall、HDevOpMultiWindowImpl、HDevEngineException。
HDevEngine类是管理全局设置。如设置或获取全局变量的值、设置脚本路径、启动停止调试模式等。
HDevProgram类加载.hdev格式文件以及获取文件内部参数一般信息。
HDevProgramCall类执行.hdev文件格式脚本,并获取变量的值。
HDevProcedure类加载.hdvp格式外部函数以及内部函数。
HDevProcedureCall类执行.hdvp外部函数和内部函数。并且可以设置或获取外部函数、内部函数参数。
HDevOpMultiWindowImpl类主要是与显示结果相关,在脚本中执行的结果可以显示在C#中。
HDevEngineException类是引擎相关的异常类。
本文档以.hdvp为例子
2..1.1 准备.hdvp函数
try *输入 Param1:=Param1 Param2:=Param2 Param3:=Param3 Param4:=Param4 if(Param1='查找模板OK' and Param2='测量成功' and Param3='测量成功' and Param4='测量成功') Result:=0 Result1:='OK' else Result:=1 Result1:='NG' endif catch (Exception) Result:=-1 ErrorString:=Exception endtry return () |
函数接口如下:5个输入,2个输出。同时添加参数文档说明(包含多种语言,需要设置需要的语言文档)。
2.1.2QT中调用该程序
全局变量
HDevEngine* MyEngine;//引擎
HDevProcedure *Program ;//函数
HDevProcedureCall* ProcCall;//函数回调
首先初始化引擎,需要设置语言和引擎文件的路径,路径设置不正确,找不到外部函数;
MyEngine = new HDevEngine(); //设置文档语言,因为使用的中文需要设置,默认英文,语言不对应拿不到参数说明 MyEngine->SetEngineAttribute("docu_language","zh_CN"); QString hdevPath="C:/Users/DH/Desktop/"; QByteArray ba = hdevPath.toLatin1(); resource_path=ba.data(); MyEngine->AddProcedurePath(resource_path); |
然后设置函数和函数回调指针,“test”为引擎文件名称,设置后会加载该引擎函数,后续可以使用回调执行。
try { Program = new HDevProcedure("test"); ProcCall = new HDevProcedureCall(*Program); }catch (HDevEngineException Ex) { ui->lineEdit_4->setText( "HDevEngine Exception"); return; } |
执行之前调用函数接口,可以查看函数的输入输出参数个数、名称、类型、以及参数说明等等。本例子参数都没htuple,图形参数使用SetInputIconicParamObject,具体接口查看"HDevEngineCpp.h"文件中HDevProcedureCall;值得注意的是输入输出都可以使用序号(从1开始)或者ParamName.
//输入个数 int num_input=Program->GetInputCtrlParamCount(); ui->textEdit->append("num_input :"+QString::number(num_input)); //输出个数 int num_output=Program->GetOutputCtrlParamCount(); ui->textEdit->append("num_output :"+QString::number(num_output)); //输入的参数名字 auto input_name= Program->GetInputCtrlParamNames(); ui->textEdit->append("input_name :"); ui->textEdit->append(input_name.ToString().Text()); //输出参数的名字 auto ouput_name=Program->GetOutputCtrlParamNames(); ui->textEdit->append("ouput_name :"); ui->textEdit->append(ouput_name.ToString().Text()); //引擎信息--没有使用到 auto QueryInfo= Program->QueryInfo(); ui->textEdit->append("QueryInfo :"); ui->textEdit->append(QueryInfo.ToString().Text()); //查询参数的信息,也就是关键字, auto QueryParamInfo= Program->QueryParamInfo(); ui->textEdit->append("QueryParamInfo :"); ui->textEdit->append(QueryParamInfo.ToString().Text()); //获取参数描述,其他字段如下 // ["assertion", "default_type", "default_value", "description", // "file_ext", "file_ext_descr", "mixed_type", "multichannel", // "multivalue", "sem_type", "stepmin", "steprec", "type_list", // "valuefunction", "value_list", "valuemax", "valuemin", "valuenumber", // "values"] ui->lineEdit_5->setText("description"); for(int k=1;k<=num_input;k++) { std::string str = ui->lineEdit_5->text().toStdString(); const char* slot=str.c_str(); auto abb=Program->GetInputCtrlParamName(k); auto a=Program->GetParamInfo(abb,slot); ui->textEdit->append(a.ToString().Text()); // auto bb=Program->GetInputCtrlParamInfo(k,slot); // ui->textEdit->append(bb.ToString().Text()); } QString a="查找模板OK"; QString b="测量成功"; HTuple Param1,Param2,Param3,Param4,Result,Result1,Exception,ErrorString,path; Param1=a.toStdString().data(); Param2=b.toStdString().data(); Param3=b.toStdString().data(); Param4=b.toStdString().data(); ProcCall->SetInputCtrlParamTuple(1,Param1); ProcCall->SetInputCtrlParamTuple(2,Param2); ProcCall->SetInputCtrlParamTuple(3,Param3); ProcCall->SetInputCtrlParamTuple(4,Param4); ProcCall->SetInputCtrlParamTuple(5,path); ProcCall->Execute();//执行函数 // auto out1 = ProcCall->GetOutputCtrlParamTuple("Result"); // auto out2 = ProcCall->GetOutputCtrlParamTuple("Result1"); // ui->textEdit->append(out1.ToString().Text()); // ui->textEdit->append(out2.ToString().Text()); for (int j=1;j<=num_output;j++) { HTuple out; ProcCall->GetOutputCtrlParamTuple(j,&out); ui->textEdit->append(out.ToString().Text()); } |
通过以上三步,引擎函数可以被调用;但是如果程序运行期间引擎进行更改,程序中不会更改;必须主动重新加载,有了这一步我们就不需要重复的启动关闭应用程序了。
分为两个步骤:SetProcedurePath会清空当前所有的路径;
然后AddProcedurePath重新添加路径
MyEngine->SetProcedurePath(""); QString hdevPath="C:/Users/DH/Desktop/"; QByteArray ba = hdevPath.toLatin1(); resource_path=ba.data(); MyEngine->AddProcedurePath(resource_path); |
2.2C++调用库函数
2.2.1多个hdvp函数生成.hdpl库函数
首先建立空白库函数,点击“函数”---“管理函数”---“管理库函数”
新建的库函数目录如果不在外部函数目录,会提醒添加,建好后右上角选中新建的函数,然后右上角添加函数,即可选择hdev文件;点击选中的库右击保存库(所有的函数就会保存到一个文件中,方便迁移,迁移添加库函数即可使用)。
2.2.2QT调用库函数
同上述调用外部函数步骤一样,
注意:第二步的函数名称需要变更为库函数中所调用的函数名,并非库函数文件名