业务逻辑从dll开始
C++环境配置
如何将UFUN
库整合到C++工程上来呢? 这里让我们从创建一个二次开发的C++编程环境开始吧!
首先西门子在C:\Program Files\Siemens\NX 8.5\UGOPEN\vs_files
就提供了一些C++工程创建模板,我们将其复制到 Visual Studio的主目录下C:\Program Files (x86)\Microsoft Visual Studio 10.0
打开我们的Visual Studio IDEA,新建项目就有这个创建模板了。就像我之前入门C++
创建Win32控制台应用程序一样简单。
入口函数和出口函数
项目创建好了之后,主程序入门mian.cpp
默认会默认提供一个出口函数 和卸载函数 当在UG中执行了此DLL时,会从此入口函数ufsta
开始执行。
/*****************************************************************************
** Activation Methods
*****************************************************************************/
/* Unigraphics Startup
** This entry point activates the application at Unigraphics startup */
extern DllExport void ufsta(char* param, int* returnCode, int rlen)
{
//获取NX二次开发许可 ,如果不能获取到 就终止此程序运行 获取成功返回0 失败则返回错误号
/* Initialize the API environment */
if (UF_CALL(UF_initialize()))
{
/* Failed to initialize */
return;
}
/* TODO: Add your application code here */
uc1601("HelloWorld End", 1);
//释放NX二次开发许可
/* Terminate the API environment */
UF_CALL(UF_terminate());
}
当入口函数执行完毕之后,NG系统会自动调用卸载函数ufusr_ask_unload
,来完成一些卸载工作。并最终向NG返回一个整形数值。
/* Unload Handler
** This function specifies when to unload your application from Unigraphics.
** If your application registers a callback (from a MenuScript item or a
** User Defined Object for example), this function MUST return
** "UF_UNLOAD_UG_TERMINATE". */
extern int ufusr_ask_unload(void)
{
return(UF_UNLOAD_UG_TERMINATE);
}
该整形数值会给NG带来不同的反馈。
#define UF_UNLOAD_IMMEDIATELY 1 // UF程序运行之后,立即从内存中卸除,即当重新修改、编译成新的DLL文件时,UG不需要关闭重启动就可以调用此新的*.DLL文件
#define UF_UNLOAD_SEL_DIALOG 2 // 通过一个卸载选择对话框来进行 来进行卸除操作。
#define UF_UNLOAD_UG_TERMINATE 3 // 返回此数值,则设置不从内存中卸除,即一直到打开此动态链接库的UG会话结束时才卸除。
运行和调试DLL
运行:
在VS中,我们可以通过点选菜单条(生成>生成解决方案
)来得到编辑链接好的动态链接库dll文件这里假定为NX8 Open Wizard1.dll
,打开UG,点选菜单条(文件>执行>NXOpen(ctrl+u)
),则NG会弹出执行用户函数窗口,找到NX8 Open Wizard1.dll
点击OK按钮。就完成了动态链接库在NG的运行。
调试:
在VS中,先对需要断点的地方设置断点,然后点选菜单条(调试>附加到进程
),则VS系统弹出附加到进程 窗口,在可用进程项中,找到ugraf.exe
进程并选中后,点击附加按钮。再运行,嘿嘿成功进入断点。
函数与数据结构
函数和模块化
在UF中,存在两种不同的UF函数命名方式,即标准命名法和固定命名法
- (1)标准命名法
从UFUN帮助手册,不难发现规律。UF_MODL Files 管理 .h
文件 .h
管理函数Function
,即 UF_MODL Files>.h>Function
所以最小的层级的函数开头的大写部分表示此函数所在 UG/Open API的库名称,所以此函数需要include
声明头文件,简单举例如下,这既是C模块化编程的体现.
头文件 函数名
uf_part.h UF_PART_new
uf_curve.h UF_CURVE_create_point
uf_modl_primitives.h UF_MODL_create_block1
- (2)固定命名法
额,可以说是早期版本的命名方式,比如uc1601()
uf5943
这种就没啥子规律而言了,虽然在后期的版本有部分保留,但随着UG的版本升级,将逐渐放弃对这些函数的支持。所以建议在使用UG的函数的时候尽量避免使用他们,以保证开发程序有延续性。
UF是完全用C语言来实现的,其中运用到了C的结构,指针和预定义常数等,因此在UF中拥有大量特定的数据结构。一般从后缀上已经对他们的类型进行了明确的标识。
类型名称下缀 | 含义 |
---|---|
_t | 原始数据结构类型 |
_p_t | 指向该结构体的指针类型 |
_s | 结构类型 |
_u_t | 联合类型 |
_u_p_t | 指向联合的指针 |
_f_t | 指向函数的指针 |
绝大部分UF函数的返回值都是整型值,其返回值表示函数执行成功与否的状态。
若返回值为0时则表示函数执行成功;
若返回值不为0则表示函数执行失败,非零的返回值就是错误号。读者在使用UF进行编程时应注意检查每一个 UF调用的返回值,若非零则应进行相应的处理,以提高代码的可靠性。
数据结构
tag_t
typedef unsigned int tag_t; // 实际上就是无符号整型起了一个别名 tag_t
typedef tag_t *tag_p_t; // tag_t的指针 也起了一个别名叫 tag_p_t
UFUN
中用的最多的数据类型,他是NX对象的唯一标识ID,他是一个无符号的整型数值。他可以是部件(part),特征(feat),草图,曲线,属性,表达式等。用来作为UG实体(entity)的ID来控制实体。
现在我们试着来创建一个工作部件并保存,以弹出框的方式输出此部件的ID,再进入到NX调试模式,查看两次tag_t 类型的ID.来验证任何NX对象在创建之后,只有一个唯一ID
#include<uf_part.h>
#include<stdio.h>
void MyClass::do_it()
{
// TODO: add your code here
UF_initialize();
uc1601("输出消息啦!*wangnaixing",1);
const char* part_name = "C:\\wnx.prt";
int units = 1;
tag_t id = NULL_TAG;
UF_PART_new(part_name, units, &id);
char msg[256];
sprintf(msg,"当前创建的部件的tagID为%d",id);
uc1601(msg,1);
UF_PART_save();
UF_terminate();
}
uf_list_p_t
我们知道一个实体、特征、面、边被创建后,都会有一个唯一的tag_t的ID,来标识这个对象。那么如何把这些对象进行一个统一的管理呢?UFUN提供了链表容器。帮助我们进行管理。uf_list_p_t
表示一个UG实体链,是一个结构。有两个成员组成,eid 表示链中的一个实体,*next 表示指向下一项的指针,具体定义如下:
头文件:uf_modl_utilities.h
struct uf_list_s {
tag_t eid ; /* Object ID */
struct uf_list_s *next; /* Pointer to the next OID in the list */
};
typedef struct uf_list_s *uf_list_p_t;
// 所以uf_list_s结构指针 等价于 uf_list_s
函数 | 功能描述 |
---|---|
UF_MODL_create_list | 创建链表。 |
UF_MODL_delete_list | 删除链表所占空间 |
UF_MODL_ask_list_count | 查询链表数量NX对象元素 |
UF_MODL_put_list_item | 往链表里面加入NX对象 |
UF_MODL_delete_list_item | 删除链表存储的某一个NX对象 |
int UF_MODL_create_list(uf_list_p_t * list ) //创建链表需要 uf_list_结构体指针的指针
int UF_MODL_ask_list_count(uf_list_p_t list, int * count)//查询链表元素个数需要 uf_list_结构体指针
int UF_MODL_put_list_item(uf_list_p_t list, tag_t obj_id) // 往链表里面添加元素 需要 uf_list_结构体指针 和对象ID
int UF_MODL_delete_list(uf_list_p_t * list) //删除链表 需要 uf_list_结构体指针的指针
int UF_MODL_delete_list_item(uf_list_p_t * list, tag_t object )//根据ID删除链表中的元素 uf_list_结构体指针的指针 和 NX对象ID
- 创建链表,并给链表添加元素,用完销毁元素。
uf_list_s* list;
UF_MODL_create_list(&list);
for (size_t i = 0; i < 3; i++)
{
UF_MODL_put_list_item(list, line1TAG[i]);
}
UF_MODL_delete_list(&list);
- 遍历链表元素
void for_each(uf_list_s* L) { //while 循环
while (L)
{
char msg[256];
sprintf(msg, "链表元素:%d", L->eid);
uc1601(msg, 1);
L = L->next;
}
cout << endl;
}
void for_each(uf_list_s* L) { // do-while
do {
char msg[256];
sprintf(msg, "链表元素:%d", L->eid);
uc1601(msg, 1);
} while (L = L->next);
cout << endl;
}
- 查询链表元素数量
UF_MODL_ask_list_count(list, &count);
show_list_count(count);
void show_list_count(int count) {
char msg[256];
sprintf(msg, "链表对象的数量为:%d", count);
uc1601(msg, 1);
}
string_list
string_list 是UFUN定义的一个数据结构,在创建有界平面的时候,有所运用。
struct string_list
{
int num; /* Number of items in the string array and the
dir array. (Min = 1, Max = 150)*/
int *string; /* <len:num> Number of items in the ID array for each string.
(Min = 1, Max = 402) */
int *dir; /* <len:num> Indication of whether the string defined in id
should start from the beginning of the first curve
or the end of the first curve. This should be set
to either UF_MODL_CURVE_START_FROM_BEGIN or
UF_MODL_CURVE_START_FROM_END. */
tag_t *id; /* <len:num> The array of items defining the string. This array
should be as long as the total of the number of
items indicated in string. Although not all
functions allow all the data types, this array can
typically include curves, faces and edges. */
}
typedef struct string_list UF_STRING_t, *UF_STRING_p_t;
函数 | 用途 |
---|---|
UF_MODL_init_string_list | 初始化 |
UF_MODL_create_string_list | 创建 |
UF_MODL_free_string_list | 释放空间 |
void UF_MODL_init_string_list(UF_STRING_p_t string_list1 );//创建string_list 需要 string_list结构的指针
void UF_MODL_create_string_list(
int num_string, //字符串数量
int num_object, //对象数量
UF_STRING_p_t string_list1 //经过初始化的string_list 最后一定要 UF_MODL_free_string_list
);
void UF_MODL_free_string_list(UF_STRING_p_t string_list); //释放内存 同初始化
内存分配与释放
针对C语言动态开辟内存空间的函数进行了封装,一般我们是用这些API来在堆区动态开辟内存空间,释放内存空间。文章来源:https://www.toymoban.com/news/detail-508306.html
void * UF_allocate_memory
(
unsigned int nbytes, //分配字节数
int * error_code //0成功
)
比如给一个double
类型的指针分配1600 字节的空间。文章来源地址https://www.toymoban.com/news/detail-508306.html
double* pts = (double*)UF_allocate_memory(sizeof(double)*200, &errorCode);
void * UF_reallocate_memory
(
void * data,
unsigned int nbytes,
int * error_code
)
void UF_free_string_array
(
int n_strings,
char * * string_array
)
void UF_free
(
void * data
)
void UF_free_string_array
(
int n_strings,
char * * string_array
)
void * UF_reallocate_memory
(
void * data,
unsigned int nbytes,
int * error_code
)
void UF_free_string_array
(
int n_strings,
char * * string_array
)
void UF_free
(
void * data
)
void UF_free_string_array
(
int n_strings,
char * * string_array
)
到了这里,关于02_业务逻辑从dll开始的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!