基于C/C++的UG二次开发流程

news2024/11/17 3:49:03

文章目录

  • 基于C/C++的UG二次开发流程
    • 1 环境搭建
      • 1.1 新建工程
      • 1.2 项目属性设置
      • 1.3 添加入口函数并生成dll文件
      • 1.4 执行程序
      • 1.5 ufsta入口
        • 1.5.1 创建程序部署目录结构
        • 1.5.2 创建菜单文件
        • 1.5.3 设置系统环境变量
        • 1.5.4 制作对话框
        • 1.5.5 创建代码
        • 1.5.6 部署和执行

基于C/C++的UG二次开发流程

1 环境搭建

UG/Open API(UG 开放应用程序接口),也称 User Function(用户函数,简称 UF)。

UF 的编程可以采用标准 C 或 C++两种方式作为开发语言(这里我们使用C++)。

针对程序运行的环境不同,UF 程序又分为外部 UF内部 UF 两种形式。

外部 UF 程序是可执行程序(*.EXE)。优点是不必启动 UG,属于后台运行,缺点是不能实现用户的交互操作。一般多用于 Part 文件大量创建、存取和管理或控制出图,而不适用于用户交互性的几何建模和修改。

内部 UF 是以**动态链接库(*.DLL)**的形式创建并编译的。UG 调用内部 UF 的方式有两种,一种是启动 UG 后,点击菜单:【文件】→【执行】→【NX 打开】,从中选择需要执行的 DLL 文件(程序入口点:ufusr),另一种则是从用户创建的菜单中(Menu Script)调出用户定制的界面(UI Styler)来运行(程序入口点:ufsta)。内部 UF在用户的交互、屏幕选取等的复杂操作上具有优势。

下文中我们主要介绍内部UF程序的开发。

1.1 新建工程

启动VS2022,由于是内部UF的开发,新建动态链接库(DLL)项目。

在这里插入图片描述

1.2 项目属性设置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

libufun.lib
libugopenint.lib
libvmathpp.lib
libnxopencpp.lib
libnxopenuicpp.lib

1.3 添加入口函数并生成dll文件

新建项目后,VS2022会默认生成framework.h、pch.h、pch.cpp、dllmain.cpp文件。接下来我们只需要修改dllmain.cpp,修改后内容如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "uf.h"				// 包含常用 UF 函数的声明
#include "uf_modl.h"		// 包含建模相关的 UF 函数声明
#include "uf_ui.h"			// 包含界面操作相关的 UF 函数声明
#include <stdio.h>

#define UF_CALL(X) (report( __FILE__, __LINE__, #X, (X)))

// 用于程序调试
static int report(char* file, int line, char* call, int irc)
{
	if (irc)
	{
		char msg[133];
		printf("%s, line %d: %s\n", file, line, call);
		(UF_get_fail_message(irc, msg)) ?
			printf("returned a %d\n", irc) :
			printf("returned error %d: %s\n", irc, msg);
	}
	return(irc);
}

// 实际工作函数
static void do_ugopen_api(void)
{
	/* 用户在此编写自己的 UF 程序 */
	/* 下面示例为创建长方体 */
	UF_FEATURE_SIGN sign = UF_NULLSIGN;
	double block_orig[3] = { 0.0,0.0,0.0 }; // 原点
	char* block_len[3] = { "1","2","3" };	// 三边长
	tag_t blk_obj;
	UF_CALL(UF_MODL_create_block1(sign, block_orig, block_len, &blk_obj)); // 调用UF_MODL_create_block1函数创建长方体
}


void ufusr(char* param, int* retcode, int paramLen)
{
	if (!UF_CALL(UF_initialize()))//获取二次开发许可 
	{
		do_ugopen_api();//实际工作函数 
		UF_CALL(UF_terminate());//释放二次开发许可 
	}
	else
	{
		uc1601("获取开发许可失败,退出!", 1);//获取二次开发许可失败,提示用户 
	}
}

// 卸载函数
int ufusr_ask_unload(void)
{
	return (UF_UNLOAD_IMMEDIATELY);//完成操作后立即从内存中卸载
}

修改属性页,将符合模式改为,防止编译运行报错“const char *“ 类型的实参与 “char *“ 类型的形参不兼容

参考文章:「VS」“const char *“ 类型的实参与 “char *“ 类型的形参不兼容
在这里插入图片描述

最后点击运行,即可得到内部UF的dll文件。

在这里插入图片描述

1.4 执行程序

打开UG,新建一个part文件。Ctrl+U打开上一步生成的DLL文件(test.dll)。UG 会执行此动态库中的入口函数ufusr,在 UG 建模工作区中生成一个长方体。
在这里插入图片描述

1.5 ufsta入口

在上面我们执行内部UF程序的方法是从ufusr入口进入(即Ctrl+U执行DLL文件),接下来我们介绍从ufsta入口进入的方法(即UI交互执行对应回调函数)。

1.5.1 创建程序部署目录结构

首先创建一个工作目录,其中分别再创建两个子目录“startup”和“application”。前者用来存放菜单文件(*.men)和动态库文件(*.dll),后者存放对话框文件(*.dlg)。
在这里插入图片描述-

1.5.2 创建菜单文件

startup目录下创建一个菜单文件(test_ufsta.men),内容如下:

VERSION 120
EDIT UG_GATEWAY_MAIN_MENUBAR
HIDE UG_HELP
!一级菜单编辑,在帮助菜单后
BEFORE UG_HELP
 CASCADE_BUTTON MENU_TestUfsta
 LABEL TestUfsta
END_OF_BEFORE 
!二级菜单编辑
MENU MENU_TestUfsta 
 BUTTON BUTTON_TestUfsta 
 LABEL 测试ufsta 
 ACTIONS TestUfsta.dlg
END_OF_MENU
1.5.3 设置系统环境变量

新建一个环境变量UGII_USER_DIR,将上面的程序工作目录作为值。

在这里插入图片描述

新建完成后,打开UG,点击菜单,即可得到我们想要的效果。
如果出现中文乱码的问题,将men文件采用ANSI编码保存即可解决。
在这里插入图片描述

1.5.4 制作对话框

UG中提供了UI Styler模块用于制作对话框UI,支持图形化操作,自动生成代码框架(类似于Qt Designer)。该模块的打开方式如下(需要先打开一个部件):

在这里插入图片描述

我们便可以得到一个最基础的对话框,左下角为预览效果,左上角为控件对象层级树,右边为控件对象属性。

在这里插入图片描述

点击界面上方工具栏中的按钮,即可在对话框中添加一个按钮。

在这里插入图片描述

接着我们将按钮的标签更改成一个我们想要名称,最后点击保存,选择使用的语言(这里选择C++),文件名为TestUfsta.dlg,保存到application目录下,

在这里插入图片描述

  • xxx.dlg。对话框资源文件。

  • xxx.hxx。对此对话框编程使用的头文件。

  • xxx_template.c。对此对话框编程使用的代码框架。

1.5.5 创建代码

和ufusr入口一样,新建一个命名为TestUfsta的DLL工程,将上一步生成的xxx.h文件拷贝到工程目录下,再将xxx_template.c文件中的一个宏定义和两个静态变量,以及ufsta(UF 的入口点)、CHANGE_apply_cb(对话框上【apply】按钮的回调函数)、CHANGE_action_0_act_cb(对话框上用户定制的【创建长方体】按钮的回调函数)三个函数复制到TestUfsta.cpp中。修改后内容如下:

#include <stdio.h> 
#include <uf.h> 
#include <uf_defs.h> 
#include <uf_exit.h> 
#include <uf_ui.h> 
#include <uf_styler.h> 
#include <uf_mb.h> 
#include <stdio.h>
#include <uf_modl.h>
#include "TestUfsta.h"

#define CHANGE_CB_COUNT ( 2 + 1 ) /* Add 1 for the terminator */
#define UF_CALL(X) (report( __FILE__, __LINE__, #X, (X)))

// 用于程序调试
static int report(char* file, int line, char* call, int irc)
{
    if (irc)
    {
        char msg[133];
        printf("%s, line %d: %s\n", file, line, call);
        (UF_get_fail_message(irc, msg)) ?
            printf("returned a %d\n", irc) :
            printf("returned error %d: %s\n", irc, msg);
    }
    return(irc);
}

// 实际工作函数
static void do_ugopen_api(void)
{
    /* 用户在此编写自己的 UF 程序 */
    /* 下面示例为创建长方体 */
    UF_FEATURE_SIGN sign = UF_NULLSIGN;
    double block_orig[3] = { 0.0,0.0,0.0 }; // 原点
    char* block_len[3] = { "1","2","3" };	// 三边长
    tag_t blk_obj;
    UF_CALL(UF_MODL_create_block1(sign, block_orig, block_len, &blk_obj)); // 调用UF_MODL_create_block1函数创建长方体
}

static UF_STYLER_callback_info_t CHANGE_cbs[CHANGE_CB_COUNT] =
{
 {UF_STYLER_DIALOG_INDEX, UF_STYLER_APPLY_CB        , 0, CHANGE_apply_cb},
 {CHANGE_ACTION_0       , UF_STYLER_ACTIVATE_CB     , 0, CHANGE_action_0_act_cb},
 {UF_STYLER_NULL_OBJECT, UF_STYLER_NO_CB, 0, 0 }
};

static UF_MB_styler_actions_t actions[] = {
    { "TestUfsta.dlg",  NULL,   CHANGE_cbs,  UF_MB_STYLER_IS_NOT_TOP },
    { NULL,  NULL,  NULL,  0 } /* This is a NULL terminated list */
};

extern void ufsta(char* param, int* retcode, int rlen)
{
    int  error_code;

    if ((UF_initialize()) != 0)
        return;

    if ((error_code = UF_MB_add_styler_actions(actions)) != 0)
    {
        char fail_message[133];

        UF_get_fail_message(error_code, fail_message);
        printf("%s\n", fail_message);
    }

    UF_terminate();
    return;
}

int CHANGE_apply_cb(int dialog_id,
    void* client_data,
    UF_STYLER_item_value_type_p_t callback_data)
{
    /* Make sure User Function is available. */
    if (UF_initialize() != 0)
        return (UF_UI_CB_CONTINUE_DIALOG);

    /* ---- Enter your callback code here ----- */

    UF_terminate();

    /* Callback acknowledged, do not terminate dialog                 */
    /* A return value of UF_UI_CB_EXIT_DIALOG will not be accepted    */
    /* for this callback type.  You must respond to your apply button.*/
    return (UF_UI_CB_CONTINUE_DIALOG);

}

int CHANGE_action_0_act_cb(int dialog_id,
    void* client_data,
    UF_STYLER_item_value_type_p_t callback_data)
{
    /* Make sure User Function is available. */
    if (UF_initialize() != 0)
        return (UF_UI_CB_CONTINUE_DIALOG);

    /* ---- Enter your callback code here ----- */
    do_ugopen_api();

    UF_terminate();

    /* Callback acknowledged, do not terminate dialog */
    return (UF_UI_CB_CONTINUE_DIALOG);

    /* or Callback acknowledged, terminate dialog.    */
    /* return ( UF_UI_CB_EXIT_DIALOG );               */

}

运行生成DLL。

对于VS2022,新建DLL工程后会默认生成和使用pch.h作为预编译头文件,为了不必要的麻烦,我们将工程属性设置为不使用预编译头文件,即可删除pch相关的文件。
在这里插入图片描述

1.5.6 部署和执行

将所生成的DLL文件拷贝到startup目录下,打开UG即可成功运行。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1130042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嚼一嚼Halcon中的3D手眼标定

文章目录 一、问题概述1、何为手眼标定&#xff1f;2、手眼标定的2种形式1&#xff09;眼在手上&#xff08;eye in hand&#xff09;&#xff1a;即相机固定在机械臂末端2&#xff09;眼在手外&#xff08;eye to hand&#xff09;&#xff1a;即相机固定在机械臂以外的地方 3…

【JVM】类的生命周期

【JVM】类的生命周期 文章目录 【JVM】类的生命周期1. 生命周期概述2. 加载阶段3. 连接阶段3.1 验证3.2 准备3.3 解析 4. 初始化阶段4.1 触发初始化的方式4.2 clinit不存在的情况4.3 多个类的初始化 5. 总结 1. 生命周期概述 类的生命周期分为5/7个阶段&#xff1a; 加载(Loa…

MSQL系列(八) Mysql实战-SQL存储引擎

Mysql实战-SQL存储引擎 前面我们讲解了索引的存储结构&#xff0c;BTree的索引结构&#xff0c;我们一般都知道Mysql的存储引擎有两种&#xff0c;MyISAM和InnoDB,今天我们来详细讲解下Mysql的存储引擎 文章目录 Mysql实战-SQL存储引擎1.存储引擎2.MyISAM的特点3. InnoDB的特…

面向小白vim使用手册

撤回上一步 按 "u" 注释多段 1&#xff1a;选择开始注释的地方&#xff0c;在命令模式下按 ctrv进入可视化模式。 2&#xff1a;鼠标向下滑动&#xff0c;选中要注释的段落&#xff1a;3:进入大写锁定&#xff0c;按"i"键进入插入模式&#xff1a; 4:输…

vue3 + ant design vue项目svg格式的background-image使用配置

直接使用的时候会报错: 图片解析不出来还是svg源文件代码 项目启动报错 vue3使用的时候普通配置会出现this.getOptions is not function错误&#xff08; Webpack 版本升级引起的&#xff0c;在较新的 Webpack 版本中&#xff0c;this.getOptions 方法已被移除。&#xff09;…

小知识(6) el-table表格选中行和回显行(vue3)

el-table表格选中行和回显行 官方文档说明 https://element-plus.org/zh-CN/component/table.html#table-%E6%96%B9%E6%B3%95 环境&#xff1a;vue3element-plus 选中行selection <el-table ref"baseTableRef" row-key"id" border :selection"tr…

支持多校 微信课表小程序源码 排课小程序源码 支持导入课表 情侣课表 背景设置

练手Lab课程表小程序源码是一个基于thinkphp系统进行开发的前后端分离系统。 源码功能介绍 1、情侣功能 2、情侣间留言 3、情侣间互相设置课程表背景 4、自己日、周课程表背景设置 5、教务系统课程表导入 6、导入别人分享的课表 7、导入别人分享的单课 8、多校支持 9…

25装饰器2

有一个比较绕的地方&#xff0c;但是我相信我能理解透彻这个里面的逻辑还有原理 def check(func):print(登录验证)def inner():func()return innerdef fss():print(发说说)fss check(fss) fss()这里的fss check(fss)还有后面的fss()什么意思&#xff1f;怎么理解呢&#xff…

Qt之彻底解决QSpinBox限定范围无效的问题

QSpinBox有个比较啃爹的问题,不管取值范围设置为多少,都能一直输入0,如下图所示: 当取值范围包含负数时,负号后也可以一直输入0,如下图所示: 还有就是当取值范围设置为10以上时,比如10~100,却可以输入1~9 虽然上述非法输入最终都未生效,当QSpinBox失去焦点时会显示为…

【iOS逆向与安全】某音App直播间自动发666 和 懒人自动看视频

1.目标 由于看直播的时候主播叫我发 666&#xff0c;支持他&#xff0c;我肯定支持他呀&#xff0c;就一直发&#xff0c;可是后来发现太浪费时间了&#xff0c;能不能做一个直播间自动发 666 呢&#xff1f;于是就花了几分钟做了一个。 2.操作环境 越狱iPhone一台 frida m…

如何使用 JMeter 进行 HTTPS 请求测试?

本文将介绍如何使用 JMeter 测试 HTTPS 请求&#xff0c;并提供相关的技巧和注意事项。 在进行性能测试时&#xff0c;很多网站都采用了 HTTPS 协议。当我们测试 HTTPS 请求&#xff0c;如果服务端开启了双向认证&#xff0c;则需要客户端发送请求时带上证书。本文介绍如何在 …

机器学习-模型评估与选择

文章目录 评估方法留出法交叉验证自助法 性能的衡量回归问题分类问题查准率、查全率与F1ROC与AUC 在机器学习中&#xff0c;我们通常面临两个主要问题&#xff1a;欠拟合和过拟合。欠拟合指模型无法在训练数据上获得足够低的误差&#xff0c;通常是因为模型太简单&#xff0c;无…

从另外一个进程中读取数据

从另外一个进程中读取数据&#xff0c;其实就注入线程&#xff0c;寻址&#xff0c;解析内存&#xff0c;处理数据。例如这个就是从另外一个正在运行的进程中&#xff0c;读取数据并保存。实时性还可以。

C/C++新冠疫情死亡率 2020年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C新冠疫情死亡率 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C新冠疫情死亡率 2020年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 2020年全世界爆发了新冠疫情&#xff0c;请…

openEuler 22.03 LTS 安装 Docker CE 和 Dcoker Compose

openEuler 使用 DNF 安装 Docker CE 1024&#xff0c;节日快乐&#xff01;回归正题&#xff0c;DNF 安装 DockerOS 系统环境准备安装 docker-ce 步骤1、更新系统2、安装必要的软件包3、添加 Docker CE 存储库4、更新索引缓存并安装 Docker CE5、启动 Docker 服务6、查看 Docke…

当前JavaEE初阶的阶段知识总结

当前JavaEE初阶的阶段知识总结 多线程 文件IO 文件系统操作 ~~ File类. 文件内容操作 ~~ 读文件,写文件. IO 流对象. 流(Stream),形象的比喻,读取文件,就像水流一样,读写文件的时候,和水流类似,读100字节,可以一次读1个字节,100次完成;也可以一次读10个字节,10次完成…… 在…

用户案例 | 珍岛集团基于 Apache DolphinScheduler 打造智能营销云平台

珍岛集团致力于打造全球领先的智能营销云平台&#xff0c;在国内率先推出的Marketingforce&#xff08;营销力&#xff09;平台&#xff0c;专注于人工智能、大数据、云计算在数字营销及企业数字化智能化领域的创新与实践&#xff0c;面向全球企业提供营销力软件及服务&#xf…

python轻量规则引擎rule-engine入门与应用实践

rule-engine是一种轻量级、可选类型的表达式语言&#xff0c;具有用于匹配任意 Python 对象的自定义语法&#xff0c;使用python语言开发。 规则引擎表达式用自己的语言编写&#xff0c;在 Python 中定义为字符串。其语法与 Python 最相似&#xff0c;但也受到 Ruby 的一些启发…

Centos8 降低gcc版本至gcc-7.3

1 首先卸载系统中的gcc sudo yum remove gcc 2 重新安装gcc-7.3 sudo dnf group install “Development Tools” 然后再次卸载gcc sudo yum remove gcc 然后发现centos-release-scl-rh已经安装了 sudo yum install centos-release-scl-rh yum -y install devtoolset-7-gcc dev…

SCAU 编译原理 实验1 词法分析实验

实验内容&#xff1a;参考附录C.1 设计一个简单语言的词法分析程序&#xff0c;要求能够正确处理关键字、运算符&#xff08;单个符号的和复合的运算符如>、>&#xff09;、分界符、标识符、常数等单词&#xff0c;以及不是单词的换行回车、注释。 #include<stdio.h&…