iCAx开思工具箱

标题: 【求助】UDO问题! [打印本页]

作者: hmjjh    时间: 2004-12-20 21:29
标题: 【求助】UDO问题!

我把清华那本书上面的那个UDO2程序试了一下,运行没有错误,但是结果不对!具体表现是:可以作出那个block,但是uc1601相关的显示却没有出现(也就是回调函数没有执行)!但是当我把block删除后可能(因为不是每次都出现,时有时无)出现 “in display event”。各位大虾帮忙看看原因是什么,顺便提下udo有什么优势!
  
主要代码如下:
void registed_display_fun(tag_t udo, void *display_context)
{
  int errorCode = UF_initialize();
  uc1601("in display event" , 1);
  errorCode = UF_terminate();  
}
  
void registed_select_fun(tag_t udo, void *select_context)
{
  int errorCode = UF_initialize();
  uc1601("in select event" , 1);
  errorCode = UF_terminate();  
}
  
void registed_fit_fun(tag_t udo, void *select_context)
{
  UF_UDOBJ_all_data_t all_data;
  char *class_name , *friendly_name;
  
  int errorCode = UF_initialize();
  uc1601("in fit event" , 1);
  
  errorCode = UF_UDOBJ_ask_udo_data ( udo, [$all_data)]
   &nbsprintErrorMessage(errorCode);
  
  errorCode = UF_UDOBJ_ask_class_data( all_data.class_id,  
    [$class_name, & friendly_name )]
   &nbsprintErrorMessage(errorCode);
  
  UF_UDOBJ_free_udo_data( [$all_data )]
  uc1601( class_name, 1);
  uc1601( friendly_name, 1);
  UF_free( class_name);
  UF_free( friendly_name );
  errorCode = UF_terminate();
}  
/*  Unigraphics Startup
**      This entry point activates the application at Unigraphics startup */
extern DllExport void ufsta( char *param, int *returnCode, int rlen )
{
    /* Initialize the API environment */
    int errorCode = UF_initialize();
  
    if ( 0 == errorCode )
    {
        /* TODO: Add your application code here */
  
        /* Terminate the API environment */
        errorCode = UF_terminate();
    }
  
    /* Print out any error messages */
   &nbsprintErrorMessage( errorCode );
}
/*  Explicit Activation
**      This entry point is used to activate the application explicitly, as in
**      "File->Execute UG/Open->User Function..." */
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{        
      double block_orig[3] = {0.0, 0.0, 0.0};
    char *block_len[3] = {"1", "2", "3"};
    tag_t block_tag;
    UF_FEATURE_SIGN sign = UF_NULLSIGN;
    
    UF_UDOBJ_class_t class_id;
    tag_t udo_tag = NULL_TAG;
    UF_UDOBJ_link_t link_defs[1];
  
//    void *select_contex;
    /* Initialize the API environment */
    int errorCode = UF_initialize();
  
    if ( 0 == errorCode )
    {
  
    UF_MODL_create_block1(sign, block_orig, block_len, [$block_tag)]
    errorCode = UF_UDOBJ_create_class("UDOTestClass", "MY_UDO", [$class_id)]
   &nbsprintErrorMessage( errorCode);
  
    errorCode = UF_UI_add_to_class_sel(class_id);
   &nbsprintErrorMessage(errorCode);
  
    errorCode = UF_UDOBJ_create_udo( class_id, [$udo_tag )]
     &nbsprintErrorMessage(errorCode);
  
    link_defs[0].link_type = 1;
    link_defs[0].assoc_ug_tag = block_tag;
    link_defs[0].object_status = 0;
  
    errorCode = UF_UDOBJ_add_links(udo_tag, 1, link_defs);
     &nbsprintErrorMessage(errorCode);
  
    errorCode = UF_UDOBJ_add_owning_links(udo_tag ,1, [$block_tag)]
     &nbsprintErrorMessage(errorCode);
  
    errorCode = UF_UDOBJ_register_display_cb(class_id, registed_display_fun);
     &nbsprintErrorMessage(errorCode);
  
    errorCode = UF_UDOBJ_register_select_cb(class_id, registed_select_fun);
     &nbsprintErrorMessage(errorCode);
  
    
    errorCode = UF_UDOBJ_register_fit_cb( class_id, registed_fit_fun);
      PrintErrorMessage(errorCode);
  
    
        errorCode = UF_terminate();
    }
  
    /* Print out any error messages */
    PrintErrorMessage( errorCode );
}
  
程序附件如下:
作者: 深夜摔键盘    时间: 2004-12-21 00:16
就是看到UDO那一章之后,我就不想再看那本书了,总觉得你作为写书的人,总该要负责任的,不能为了钱,把良心都丢了,你就多花点时间,把代码好好调调,打打注释,不会把你累死,可他们就是不那么干。弄到现在,全中国,就那一本书还不让人如意。看了那书,甚至都觉得所谓清华亦不过而而。还是看文档吧。
  
清华的书里所举的那个UDO的例子不标准,可以说它什么问题都没说明白也不为过。当时我调那个例子时,也出现问题。我记得当时好象实在没办法,就在程序的最后加了一句:UF_DISP_add_item_to_display,才触发显示回调。
  
UGOPEN文件夹里有一个UDO的例子,那个虽然代码长了点,但是它可以告诉你UDO能用来干什么!!!
作者: 深夜摔键盘    时间: 2004-12-21 00:19
UDO技术中有一点点面向对象的意思。所谓UDO,有两个意思:UDO类,UDO对象。前者可以视为C++中的类,是虚的,什么也不做,就是一个名字吧。后者是这个类的实例,是实际的东西。
  
UDO类,通常是在UG启动时创建的,这样在整个UG运行期间,UDO类始终存在。它允许用户在类中定义一些自己的数据,像是C++中的类成员变量。
  
UDO对象,通常是在UG运行时,动态创建的。
  
标准的用法是写两个dll,一个 dll采用ufsta入口,放在udo文件夹中,随UG启动而加载,创建UDO类并将其加入到选择列表中。同时定义各回调函数,并register them。
另一个dll只负责创建UDO对象,  入口是ufusr,每创建一个对象后,我是都来一个UF_DISP_add_item_to_display的。
  
其他的难点,就在那些与UG对象的连接,还有自有连接上了。这些我没有试过。
  
清华的书里所举的例子是将UDO类的创建和UDO对象的创建搞到一起了,入口只是ufusr的,不能放在udo文件夹下,因为UG启动时,不能创建几何对象的。兄弟你的程序中有两个入口了,不对。
  
想搞清楚一下UDO,就看看文档中uf_udobj.h的介绍中所给的两个实例。
作者: huashanyjj    时间: 2004-12-21 16:03
怎么没有出现楼主的问题“但是当我把block删除后可能(因为不是每次都出现,时有时无)出现 “in display event”。”,每次都出现了。
  
以前倒是做过一个公差的项目,用到过udo,就是零件尺寸改变的时候,标公差值自动更新,还比较好。
作者: 深夜摔键盘    时间: 2004-12-21 17:39
这儿也不对。
extern int ufusr_ask_unload( void )
{
     return( UF_UNLOAD_UG_TERMINATE );//改成这个
}
试了试, fit 和select回调不行,晚上再看了。
作者: hmjjh    时间: 2004-12-21 17:43
to huashangyjj:
   不知道huashangyjj兄是运行了我的代码,还是自己做过。我这个运行时出现的问题其实不只我上面说的,还有很多比如有时候block都不出来,错误提示是:内存错误!请hua兄详细说明“没有出现问题”的意思。莫非是键盘兄说的错误?
   另外谢谢键盘兄的解答。
   个人也觉得清华那本书错误很多。真的很难称为一本指导UG二次开发的“好书”!
作者: huashanyjj    时间: 2004-12-21 19:57
我用的是楼主的程序,
在执行了第一次user function后,删除了block,出现了 “in display event”;撤销删除后,再次删除,还是出现了 “in display event”,但是select fit的功能确实没有出来。
在执行第二次user function后,删除了block,没有出现了 “in display event”。推其原因是,udo类已经创建(这个类创建了一直随着ug而存在,除非删除该类),所以第二次创建类不成功,这时用class_id(可能是0)加入sel和创建udo链接都没有作用了。
select fit为何没有实现,我还没有仔细看。
作者: 深夜摔键盘    时间: 2004-12-21 21:18
这个block 的UDO创建后,如果不用UF_DISP_add_item_to_display, block创建后,是不会触发显示回调的。
作者: hmjjh    时间: 2004-12-21 21:35
to huashanyjj  与键盘兄:
   按照键盘兄的意思,我把上面的程序分成两个dll,其一dll的作用是udo类的创建,callback函数的定义(请问键盘兄是否只需要声明一下,在下面的dll中具体实现?),并把链接后的dll文件放到$(UGII_USER_DIR)\udo下面;另一个dll就是创建udo对象,同时创建链接与只有链接,并放到$(UGII_USER_DIR)\application下面。在创建block之后也加上了UF_DISP_add_item_to_display(blk_tag)。现在可以多次执行第二个dll而不会有内存错误。再次感谢键盘兄的指点!
  现在还有一个问题:第二个dll在编译过程中提示udo类没有初始化。也就是不能识别dll一中创建的udo类。按照帮助文档的说明,在编译第二个dll是要添加第一个dll的lib文件,我把此lib文件(以及debug力相关的文件)全部拷到ugopen目录(即libufun等存放的目录)下面。自己也感觉这样是不行,因为udo类没有定义啊,但不知道怎么搞,是否要输出这个类的头文件啊?
  
作者: 深夜摔键盘    时间: 2004-12-21 22:09
这个udo类id,要在dll中使用一个输出函数中返回的。
如下:
UF_UDOBJ_class_t class_id;
  
extern DllExport UF_UDOBJ_class_t get_class_id(void)
{
   return class_id;
}
  
在另一个dll添加第一个dll的lib后:可如此:
UF_UDOBJ_class_t temp_class_id=get_class_id(void);
  
只是纳闷,以前试过fit回调是可以的,但现在触发不了 它了。
作者: hmjjh    时间: 2004-12-22 09:46
经过键盘兄的指导,基本可以用了。键盘兄“不可以的‘fit’回调”我是可以了。不过我的“select”回调还是不行(不管它了,^_^,关键是知道UDO怎么搞就行)。大家要是要看看的话,我就把程序稍微注释一下发上来。这是大家共同讨论的结果,^_^!
  
另外再问键盘兄一个相关的话题:引用外部函数比如这里的get_class_id有三种方法:
(1)键盘兄所说的方法,设置udo类为static UF_UDOBJ_class_t class_id;
建立外部函数返回,
static UF_UDOBJ_class_t class_id;
extern DllExport UF_UDOBJ_class_t get_class_id(void)  
{  
   return class_id;  
}  
(2)用.def文件输出,.def文件格式如下(不对请指教)
LIBRARY pro_name
EXPROT
get_class_id
(3)(我不知道,希望高手补充,^_^)
  
ps:前提条件是要把两个工程文件放到一个工作区中去,并且设置udo_obj工程dependencies 建立udo类的工程
作者: hmjjh    时间: 2004-12-22 10:16
程序附件(包含两个工程,请放到一个工作区下面进行编译)
作者: 深夜摔键盘    时间: 2004-12-22 15:04
class_id还可以在dll中作为输出变量。
如果有n多个 class_id需要共享,可以用内存映射。
作者: hmjjh    时间: 2005-1-3 10:32
谢谢各位的帮忙,^_^
作者: lita_2005    时间: 2005-4-14 16:19
ugs是迈关子高手,一点也不奇怪




欢迎光临 iCAx开思工具箱 (https://t.icax.org/) Powered by Discuz! X3.3