CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

应用程序之间的通信

2023-1-1 00:28| 发布者: admin| 查看: 439| 评论: 0|来自: AutoCAD

一个应用程序中的 ObjectARX 函数用于调用由其他 ObjectARX 应用程序定义和实现的外部函数。调用 by 的外部函数必须由当前加载的 ObjectARX 应用程序定义。acedInvoke()acedInvoke()

该函数按其应用程序在调用中指定的名称调用外部函数,该名称是 AutoLISP 调用该函数的函数名称。如果外部函数被定义为 AutoLISP 命令,并且其名称的前缀为“C:”,那么这些字符必须包含在指定的字符串中(就像使用 AutoLISP 表达式调用命令时一样)。acedInvoke()acedDefun()acedInvoke()

危险:由于同时加载的应用程序不能具有重复的函数名称,因此在设计使用多个程序文件的应用程序时,应考虑到这一点;避免使用确保每个外部函数的名称唯一的命名方案或约定的问题。

外部函数的名称及其所需的任何参数值以结果缓冲区链表的形式传递到。它还在结果缓冲区列表中返回其结果;第二个参数 to是结果缓冲区指针的地址。acedInvoke()acedInvoke()

以下示例函数调用示例程序事实中的阶乘函数.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

以下摘录显示了实际上如何修改函数.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; 
}

如代码示例所示,第一个参数 to 是函数指针(以源代码中定义的函数处理程序命名),而不是由 AutoLISP or 定义和调用的外部函数名称。两者并传递相同的整数函数代码。acedRegFunc()acedDefun()acedInvoke()acedDefun()acedRegFunc()i

如果已注册的函数要检索参数,则必须通过调用自己的参数来实现。acedGetArgs()

调用被移动到函数内。结果缓冲区指针是一个变量而不是一个参数。(这与此示例中其他地方对函数的调用不匹配。如果注册了所有外部函数,如本例所假设的那样,可以完全删除该函数;请参阅此示例后面的注释。新代码以粗体显示: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_tan()调用B_sin()
  • A_tan()调用C_cos()
  • B_sin()调用A_pi()
  • C_cos()调用A_pi()

其中应用程序 A 定义沙子,应用程序 B 定义,应用程序 C 定义。该函数必须由注册者注册。A_tan() A_pi()B_sin()C_cos()A_pi()acedRegFunc()

若要防止报告注册错误,请注册要用来调用的任何外部函数。acedInvoke()acedInvoke()

也可以调用该函数来注销外部函数。同一应用程序必须注册或注销函数;ObjectARX 禁止一个应用程序直接管理另一个应用程序。acedRegFunc()


路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 15:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部