Halcon12 使用Halcon的Engine直接执行程序无需写外部代码

本文介绍如何在Halcon12中利用Engine功能,直接运行程序而无需编写外部代码。通过示例展示Wpf页面的应用,并提供了详细注释的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先丢Wpf页面出来
在这里插入图片描述

照例丢代码 反正注释写的清楚

namespace HalconWpf_Engine
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region
        private HDevEngine MyEngine = new HDevEngine();
        // 实例化程序触发
        private HDevProgramCall ProgramCall;
        // HALCON 窗口句柄
        private HWindow Window;


        #endregion
        public MainWindow()
        {
            InitializeComponent();

        }
    /// <summary>
    /// 获取 外部函数存放路径
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ProcedurePath_Click(object sender, RoutedEventArgs e)
    {
        //获取 外部函数存放路径
        FolderBrowserDialog ProcedurePath = new FolderBrowserDialog();
        //如果未成功获取
        if (ProcedurePath.ShowDia
<think>我们正在处理的是用户关于C#中执行Halcon脚本并调用外部函数的问题。根据引用[2]和[3],我们知道用户希望通过C#调用Halcon引擎来执行脚本,特别是调用外部函数(.hdvp文件)。这样可以避免重新编译C#程序,只需修改脚本即可。但是,用户可能遇到了内存泄漏、路径问题或函数调用错误等问题。 解决方案步骤: 1. **环境准备**: - 在C#项目中添加对`halcondotnet.dll`和`hdevenginedotnet.dll`的引用(如引用[3]所示)。 - 确保Halcon的运行时环境正确安装,并且这些DLL的版本与安装的Halcon版本一致。 2. **初始化引擎并加载脚本**: - 创建`HDevEngine`实例,并设置`HDevProcedure`或`HDevProgram`来加载外部函数文件(.hdvp)或脚本文件(.hdev)。 3. **调用外部函数**: - 通过`HDevProcedureCall`来调用外部函数,并传递参数。 4. **常见问题及解决**: - **路径问题**:确保外部函数文件的路径正确,可以使用绝对路径。 - **内存泄漏**:由于Halcon引擎不会自动释放资源,需要手动释放。在每次调用完成后,及时释放`HDevProcedureCall`、`HDevProcedure`以及引擎对象,并调用垃圾回收。 - **函数名冲突**:如引用[1]所述,注意本地函数和外部函数同名的问题。在调用时,要确保调用的函数是外部函数,并且没有同名的本地函数干扰。 - **参数传递错误**:确保传递的参数类型和数量与外部函数定义一致。 5. **代码示例**: 下面是一个示例代码,展示如何调用外部函数: ```csharp using HalconDotNet; public void CallExternalFunction() { // 初始化引擎(只需一次) HDevEngine engine = new HDevEngine(); // 设置外部函数查找路径(可选) engine.SetProcedurePath("你的外部函数目录"); try { // 加载外部函数文件(.hdvp) HDevProcedure procedure = new HDevProcedure("外部函数名"); // 注意:这里外部函数名,不是文件名 // 创建过程调用 HDevProcedureCall procCall = procedure.CreateCall(); // 设置输入参数(如果有) procCall.SetInputCtrlParamTuple("参数名1", 值1); procCall.SetInputCtrlParamTuple("参数名2", 值2); // 设置输入图像参数(如果有) procCall.SetInputIconicParamObject("图像参数名", 图像对象); // 执行 procCall.Execute(); // 获取输出参数 HTuple result = procCall.GetOutputCtrlParamTuple("输出参数名"); HObject resultImage = procCall.GetOutputIconicParamObject("输出图像名"); // 处理结果... // 释放资源(重要!) procCall.Dispose(); procedure.Dispose(); } catch (HDevEngineException ex) { // 处理异常 HTuple errorMessage = engine.GetErrorMessage(); // 输出错误信息 } finally { // 最后,释放引擎(如果需要,通常引擎可以重复使用,所以不一定立即释放) // engine.Dispose(); } } ``` 6. **内存管理**: - 每次调用完成后,及时调用`Dispose()`方法释放资源。 - 使用`using`语句块确保资源被释放: ```csharp using (HDevProcedure procedure = new HDevProcedure("外部函数名")) using (HDevProcedureCall procCall = procedure.CreateCall()) { // 设置参数并执行 } ``` 7. **调试技巧**: - 先在Halcon中测试外部函数,确保函数本身正确。 - 在C#中捕获异常并获取Halcon引擎的详细错误信息(如上述代码中的`engine.GetErrorMessage()`)。 - 使用Halcon的窗口在C#中显示图像,帮助调试。 8. **性能优化**: - 避免频繁创建和销毁引擎,可以重用引擎和已加载的函数(但注意内存泄漏)。 - 对于大图像,确保及时释放不再使用的图像对象。 通过以上步骤,用户应该能够在C#中成功调用Halcon外部函数。如果问题仍然存在,请检查Halcon版本兼容性以及外部函数的定义是否正确。 §§相关问题§§ 1. 如何解决Halcon引擎在C#中调用时的内存泄漏问题? 2. 如何在C#中捕获并显示Halcon引擎的详细错误信息? 3. 如何重用Halcon引擎以提高性能?</think>### C#调用Halcon外部函数(.hdvp)的完整方法与问题解决方案 #### 一、核心实现步骤 1. **环境配置** ```csharp // 添加必须的引用 using HalconDotNet; using System.IO; // 初始化引擎(全局只需一次) HDevEngine engine = new HDevEngine(); engine.SetProcedurePath(@"C:\HalconScripts"); // 设置外部函数搜索路径[^2] ``` 2. **加载外部函数** ```csharp // 加载.hdvp文件中的函数 HDevProcedure myProcedure = new HDevProcedure("custom_detect"); // 函数名非文件名[^1] HDevProcedureCall procCall = myProcedure.CreateCall(); ``` 3. **参数传递与执行** ```csharp try { // 设置输入参数 procCall.SetInputCtrlParamTuple("threshold", 0.85); procCall.SetInputIconicParamObject("input_image", hImage); // 执行函数 procCall.Execute(); // 获取输出 HTuple result = procCall.GetOutputCtrlParamTuple("defect_count"); HObject defectRegion = procCall.GetOutputIconicParamObject("defect_region"); } catch (HDevEngineException ex) { HTuple errorMsg = engine.GetErrorMessage(); // 获取Halcon原生错误[^2] Console.WriteLine($"错误: {errorMsg.S}"); } ``` #### 二、常见问题及解决方案 | 问题现象 | 原因 | 解决方案 | |---------|------|---------| | **"Procedure not found"** | 1. 路径未正确设置<br>2. 函数名拼错误 | 1. 使用`engine.SetProcedurePath()`设置绝对路径<br>2. 用HDevelop打开.hdvp确认函数名[^1] | | **内存泄漏** | 未释放Halcon对象 | 添加资源释放代码:<br>`procCall.Dispose();`<br>`myProcedure.Dispose();` | | **参数类型错误** | C#与Halcon类型不匹配 | 使用正确参数类型:<br>- 标量:`SetInputCtrlParamTuple()`<br>- 图像:`SetInputIconicParamObject()` | | **版本兼容问题** | Halcon运行时版本不一致 | 1. 检查`hdevenginedotnet.dll`版本<br>2. 在HDevelop中导出匹配版本函数[^3] | | **函数执行卡死** | 死循环或资源冲突 | 1. 在HDevelop中单独测试函数<br>2. 添加超时机制:<br>`procCall.Execute(5000); // 5秒超时` | #### 三、最佳实践建议 1. **路径处理技巧** ```csharp // 动态获取脚本路径 string scriptDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scripts"); engine.SetProcedurePath(scriptDir); ``` 2. **内存管理方案** ```csharp // 使用using自动释放资源 using (HDevProcedure proc = new HDevProcedure("custom_func")) using (HDevProcedureCall call = proc.CreateCall()) { call.SetInputCtrlParamTuple("param", 100); call.Execute(); // ...处理结果 } // 自动释放资源 ``` 3. **调试与日志** ```csharp // 启用详细日志 engine.SetEngineAttribute("debug", "true"); // 获取执行日志 string executeLog = call.GetExecuteInfo("execution_time"); ``` #### 四、工业场景优化 1. **脚本热更新机制** ```csharp // 监视脚本目录变化 FileSystemWatcher watcher = new FileSystemWatcher(scriptDir); watcher.Changed += (s, e) => { engine.ResetAllProcedures(); // 重新加载函数[^2] }; ``` 2. **错误恢复设计** ```csharp // 故障时切换备用函数 try { procCall.Execute(); } catch { HDevProcedure backupProc = new HDevProcedure("backup_detect"); backupProc.CreateCall().Execute(); } ``` > **关键提示**:对于FPC检测等工业场景,建议将核心算法封装为多个小型.hdvp函数,通过C#协调调用实现模块化更新[^3]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值