应用程序之间的通信
一个应用程序中的 ObjectARX 函数用于调用由其他 ObjectARX 应用程序定义和实现的外部函数。调用的外部函数必须由当前加载的 ObjectARX 应用程序定义。acedInvoke()acedInvoke() 该函数通过其应用程序在调用中指定的名称调用外部函数,该名称是 AutoLISP 调用以调用函数的函数名称。如果外部函数定义为 AutoLISP 命令,并且使用“C:”作为其名称的前缀,则这些字符必须包含在指定的字符串中(例如,当使用 AutoLISP 表达式调用命令时)。acedInvoke()acedDefun()acedInvoke() 危险:由于同时加载的应用程序不能具有重复的函数名称,因此在设计使用多个程序文件的应用程序时应考虑到这一点;避免使用确保每个外部函数的名称唯一的命名方案或约定的问题。
外部函数的名称及其所需的任何参数值都以结果缓冲区的链表的形式传递给外部函数。它还在结果缓冲区列表中返回其结果;第二个参数是 result-buffer 指针的地址。acedInvoke()acedInvoke() 以下示例函数调用示例程序中的阶乘函数fact.cpp:acedInvoke()fact() static void test() { int stat, x = 10; struct resbuf *result = NULL, *list; // Get the factorial of x from file fact.cpp. list = acutBuildList(RTSTR, "fact", RTSHORT, x, RTNONE); if (list != NULL) { stat = acedInvoke(list, &result); acutRelRb(list); } if (result != NULL) { acutPrintf("\nSuccess: factorial of %d is %d\n", x, result->resval.rint); acutRelRb(result); } else acutPrintf("Test failed\n"); } 如果要用 调用函数,则定义该函数的应用程序应通过调用 来注册该函数。(在某些情况下,调用是必需的,如本节后面所述。当调用以注册函数时,ObjectARX 会直接调用该函数,而无需经过应用程序的调度循环。若要定义函数,请调用 。acedInvoke()acedRegFunc()acedRegFunc()acedRegFunc()acedRegFunc() 注册的外部函数处理程序必须没有参数,并且必须返回一个整数(这是应用程序结果代码之一 - 或 )。acedRegFunc()RSRSLTRSERR 以下摘录显示了如何修改 fact.cpp 中的函数以注册其函数并定义它们:funcload() typedef int (*ADSFUNC) (void); // First, define the structure of the table: a string // giving the AutoCAD name of the function, and a pointer to // a function returning type int. struct func_entry { char *func_name; ADSFUNC func; }; // Declare the functions that handle the calls. int fact (void); // Remove the arguments int squareroot (void); // Here we define the array of function names and handlers. // static struct func_entry func_table[] = { {"fact", fact}, {"sqr", squareroot}, }; ... static int funcload() { int i; for (i = 0; i < ELEMENTS(func_table); i++) { if (!acedDefun(func_table[i].func_name, i)) return RTERROR; if (!acedRegFunc(func_table[i].func, i)) return RTERROR; } return RTNORM; } 如代码示例所示,第一个参数是函数指针(以源代码中定义的函数处理程序命名),而不是由 AutoLISP 或 .两者 和 传递相同的整数函数代码。acedRegFunc()acedDefun()acedInvoke()acedDefun()acedRegFunc()i 如果已注册的函数要检索参数,则必须通过调用 来实现。acedGetArgs() 调用将移动到函数 中。result-buffer 指针是变量,而不是参数。(这与此示例中其他位置的函数中的调用不匹配。如果注册了所有外部函数,如本示例所述,则可以完全删除该函数;请参阅此示例后面的注释。新代码以粗体显示:acedGetArgs()fact()rbfact()dofun()dofun() static int fact() { int x; struct resbuf *rb; rb = acedGetArgs(); if (rb == NULL) return RTERROR; if (rb->restype == RTSHORT) { x = rb->resval.rint; // Save in local variable. } else { acdbFail("Argument should be an integer."); return RTERROR; } if (x < 0) { // Check the argument range. acdbFail("Argument should be positive."); return RTERROR; } else if (x > 170) { // Avoid floating-point overflow. acdbFail("Argument should be 170 or less."); return RTERROR; } acedRetReal(rfact(x)); // Call the function itself, and // return the value to AutoLISP. return RTNORM; } 必须对 进行类似的更改。squareroot() 注意:如果应用程序调用为其定义的每个外部函数注册处理程序,则它可以假定这些函数将由 调用,并且可以在其函数中省略大小写。如果设计的应用程序需要多个 ObjectARX 代码文件,则此方法更可取,因为它将处理函数调用的负担放在 ObjectARX 库而不是函数上。acedRegFunc()acedInvoke()kInvkSubrMsgacrxEntryPoint()acrxEntryPoint()
如果函数调用启动的调用序列导致调用同一应用程序中的函数,则后一个函数必须由 注册。如果未注册调用的函数,则报告错误。下图说明了这种情况:acedInvoke()acedRegFunc()acedInvoke() ![]() 在上图中,
其中,应用程序 A 定义 和 ,应用程序 B 定义 ,应用程序 C 定义 。该函数必须由 注册。A_tan() A_pi()B_sin()C_cos()A_pi()acedRegFunc() 若要防止报告注册错误,请注册要使用 调用的任何外部函数。acedInvoke()acedInvoke() 也可以调用该函数来注销外部函数。同一应用程序必须注册或注销该函数;ObjectARX 禁止一个应用程序直接管理另一个应用程序。acedRegFunc() 父主题: |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-3-14 07:53
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.