TC二次开发之ITK开发自学笔记(二)

文章介绍了Teamcenter的ITK开发,建议使用C++而非C,提供了API学习资源和快速创建ITK项目的建议,包括自定义模板的使用。还讨论了在Linux环境下编译ITK项目时的注意事项,如源代码格式和makefile的使用。
摘要由CSDN通过智能技术生成

    十多年前,记录了下ITK自学笔记的第一篇,后来本人从TC阵营转到达索阵营,这事就没有后续了。2022年,我又回TC阵营看了下,故续上此篇。

    1.Teamcenter的ITK开发,有两个选择:C或则C++,我个人建议选C++,理由是:相关的支持要多些。ITK的开发,甚至到整个制造业的开发,绝大多数情况下,是不用考虑运行效率的,只有少量的大文件或者大批量操作,才会考虑运行效率。而从C到C++,运行效率并不会降低太多,而在很多时候,可选择的余地,会大很多。

    2.关于API的使用参考,大约有如下途径:1)看看网上搜索到的Teamcenter二次开发培训教材。Teamcenter的生态和资源,确实比达索的系统强很多,很多时候,达索的东西在百度上找不到,而Teamcenter一找一大片;2)看看西门子官方提供的帮助文档和在线文档;3)直接去.h头文件所在的目录搜索相关的关键字。这些头文件,都有比较好的注释,可以先看看,然后猜猜,最后试试,往往就能解决困扰你许久的问题。

    3.关于快速新建ITK项目。因为ITK项目有很多自己独特的参数和配置,所以创建ITK项目是一个麻烦的事情,而且每个人的创建风格不一样,多个ITK项目就显得比较凌乱。有一个好消息是:不知道从VS 2012还是VS 2015开始,VS开始支持C++项目模板的导出了(以前只能导出C#/VB.NET模板),所以,一个比较好的做法就是:先自己写一个ITK项目,然后导成模板,供所有人使用。我这里提供一个我自己写的模板:https://gitee.com/super_admi/teamcenter.git

     部分代码摘录如下:

    

/************************************
 * 描述:本文件主要用于存放通用的逻辑声明
 * 公司:我们公司
 * 时间:2022-02-22
 ************************************/
#pragma once

#include <user_exits/user_exits.h>
#include <user_exits/epm_toolkit_utils.h>
#include <server_exits/user_server_exits.h>
#include <epm/epm.h>
#include <epm/signoff.h>
#include <bom/bom.h>
#include <bom/bom_msg.h>
#include <tccore/grm_msg.h>
#include <tccore/tc_msg.h>
#include <tccore/custom.h>
#include <tccore/aom.h>
#include <tccore/aom_errors.h>
#include <tccore/aom_prop.h>
#include <tccore/grm_msg.h>
#include <tccore/tc_msg.h>
#include <tccore/tctype.h>
#include <sa/groupmember.h>
#include <sa/user.h>
#include <tc/preferences.h>

#if !defined(SITE)
#error 'SITE' is not defined
#endif

#if !defined(VER)
#define VER 1.0
#endif

#if !defined(ROW_SEPARATOR)
#define ROW_SEPARATOR "******************************************************\n"
#endif

#if !defined(MAX_MESSAGE_SIZE)
#define MAX_MESSAGE_SIZE 2000
#endif

#if !defined(VISIBLE)
#ifdef _WIN32
#define VISIBLE
#else
#define VISIBLE __attribute__ ((visibility("default")))
#endif
#endif

#define BEGIN int ifail = ITK_ok
#define END return (ifail)
#define CHECK(func)	{ if (ITK_ok != (ifail = func)){\
char* err_string = NULL;\
EMH_ask_error_text(ifail, &err_string);\
info_syslog ("*ERROR: %d, ERROR MSG: %s.\n", ifail, err_string);\
info_syslog ("*FUNCTION: %s, FILE: %s, LINE: %d.\n", #func, __FILE__, __LINE__);\
if(NULL != err_string) MEM_free (err_string); }}
#define EX_STRING(text) TO_STRING(text)
#define TO_STRING(text) #text
#define CALLBACKS(site) site##_register_callbacks()

typedef int (*OUR_object_func) (tag_t);

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:打印日志信息
/// </summary>
/// <param name="format">格式化字符串</param>
/// <param name="...">日志内容</param>
void info_syslog(const char* format, ...);

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:打印欢迎信息
/// </summary>
void show_welcome();

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:获取流程中的任务对象
/// </summary>
/// <param name="task">流程</param>
/// <param name="count">对象数量</param>
/// <param name="attachments">任务对象</param>
/// <returns>操作是否成功</returns>
int get_task_attachments(tag_t task, int* count, tag_t** attachments);

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:遍历处理任务中的关联对象
/// </summary>
/// <param name="task">流程任务</param>
/// <param name="action">流程功能</param>
/// <param name="func">处理函数</param>
/// <returns>操作是否成功</returns>
int foreach_task_attachments(tag_t task, EPM_action_t action, OUR_object_func func);

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:判断对象类型
/// </summary>
/// <param name="object">对象</param>
/// <param name="parent_type_name">类型</param>
/// <returns>是否 parent_type_name 类型的对象</returns>
logical is_type_of(tag_t object, const char* parent_type_name);

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:是否包含对象
/// </summary>
/// <param name="objects">所有对象</param>
/// <param name="count">对象数量</param>
/// <param name="object">当前对象</param>
/// <returns>objects 是否包含 object</returns>
logical is_contains(tag_t* objects, int count, tag_t object);
/************************************
 * 描述:本文件为程序入口(main)相关内容实现
 * 公司:我们公司
 * 时间:2022-02-22
 ************************************/
#include "actions.hxx"
#include "conditions.hxx"
#include "handlers.hxx"
#include "properties.hxx"
#include "services.hxx"
#include "start.hxx"

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:初始化注册,主要用于注册 handler 函数
/// </summary>
/// <param name="decision"></param>
/// <param name="args"></param>
/// <returns>是否成功注册</returns>
int OUR_gs_shell_init_module(int* decision, va_list args) {
    BEGIN;
    *decision = ALL_CUSTOMIZATIONS;
    info_syslog(ROW_SEPARATOR);
    REGISTER_HANDLERS(SITE, decision, args);
    END;
}

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:初始化注册,主要用于注册对象的前后处理函数
/// </summary>
/// <param name="decision"></param>
/// <param name="args"></param>
/// <returns>是否成功注册</returns>
int OUR_init_module(int* decision, va_list args) {
    BEGIN;
    *decision = ALL_CUSTOMIZATIONS;
    info_syslog(ROW_SEPARATOR);
    REGISTER_CONDITIONS(SITE, decision, args);
    REGISTER_ACTIONS(SITE, decision, args);
    REGISTER_PROPERTIES(SITE, decision, args);
    END;
}

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:初始化注册,主要用于注册服务类函数
/// </summary>
/// <param name="decision"></param>
/// <param name="args"></param>
/// <returns>是否成功注册</returns>
int OURSERVICE_register_methods(int* decision, va_list args) {
    BEGIN;
    *decision = ALL_CUSTOMIZATIONS;
    info_syslog(ROW_SEPARATOR);
    REGISTER_SERVICES(SITE, decision, args);
    END;
}

/// <summary>
/// 公司:我们公司
/// 作者:李云
/// 时间:2022-01-23
/// 描述:注册用的 ITK DLL 入口函数
/// </summary>
/// <param name="SITE">动态库(站点)名称</param>
/// <returns>是否成功注册</returns>
extern "C" DLLAPI VISIBLE int START(SITE) {
    BEGIN;
    show_welcome();
    info_syslog(ROW_SEPARATOR);
    REGISTER_EXIT(SITE, _gs_shell_init_module);
    REGISTER_EXIT(SITE, _init_module);
    REGISTER_EXIT(SITE, SERVICE_register_methods);
    info_syslog("*The library file '%s.dll(.so)' loaded.\n\n", EX_STRING(SITE));
    END;
}

    4.关于ITK项目在LINUX下的编译问题。这里一般需要注意两个问题:1)使用UTF-8格式来保存源代码;2)使用makefile来控制编译过程。这两点在我提供的ITK模板项目中均有体现。

makefile文件摘录:

    

# 请根据实际情况修改此处的SITE值和TC_ROOT路径
SITE = lib_template_itk
TC_ROOT = /usr/Siemens/Teamcenter13

DEBUG = -g
USER_INCLUDE = -I.
USER_LIB =

CC = gcc
LD = gcc

SRCS = $(wildcard *.cpp)
OBJS = $(patsubst %.cpp, %.o, $(SRCS))

DEFINES=-fvisibility=hidden -c -fPIC -m64 -DPOSIX -DIPLIB -DNO_DOT_H -DSITE=${SITE}
# -I指定头文件目录
INCLUDES = ${USER_INCLUDE} -I${TC_ROOT}/include -I${TC_ROOT}/include_cpp
# -L指定库文件目录,-l指定静态库名字(去掉文件名中的lib前缀和.a后缀)
LIBS = ${USER_LIB} -L${TC_ROOT}/lib -ltc

CFLAGS = ${DEFINES} ${INCLUDES} ${DEBUG} -c

TARGET = ${TC_ROOT}/lib/${SITE}.so

.PHONY:all clean

all: $(TARGET)
# 链接时候指定库文件目录及库文件名
$(TARGET): $(OBJS)
	$(LD) -shared -o $@ $^ $(LIBS)
 
# 编译时候指定头文件目录
%.o:%.cpp
	$(CC) $(CFLAGS) $^

clean:
	rm -f $(OBJS) $(TARGET)

    5.本文不解决任何业务上的问题,需要实现某些业务调用的API,可以在培训文档或者官方参考里找到。其它的东西,均体现在本人提供的ITK模板项目中.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值