acutRelRb(result);

}

else

acutPrintf("Test failed\n");

}

Если функция, как предполагается, будет вызвана с acedInvoke(), приложение, которое определяет это, должен регистрировать функцию, вызывая acedRegFunc(). (В некоторых случаях acedRegFunc() запрос требован, как описано позже в этой секции.)

Когда acedRegFunc() вызван, чтобы регистрировать функцию, ObjectARX вызывает функцию непосредственно, без того, чтобы пройти цикл отправки приложения. Чтобы определять функцию, вызовите acedRegFunc ().

Внешний функциональный обработчик, зарегистрированный acedRegFunc() не должен иметь никакие параметры и должен возвратить целое число (который является одним из прикладного результата, закодирует — или RSRSLT или RSERR).

Следующая выборка показывает, как funcload () функция в fact. cpp может изменяться, чтобы регистрировать ее функции также как определять их:

typedef int (*ADSFUNC) (void);

// Сначала, определите структуру таблицы: строка, дающая имя AutoCAD функции,

// и указателя на функцию, возвращающую тип int.

struct func_entry {char *func_name; ADSFUNC func;};

// Объявить функции, которые обрабатывают, вызывает.

int fact (void); // Remove the arguments

int squareroot (void);

// Здесь мы определяем массив имен функции и обработчиков.

//

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;

}

Как показывают выборки кода, первый параметр к acedRegFunc () - указатель функции (названный по имени функциональный обработчик, определенный в исходном тексте), а не внешнее имя функции, определенное acedDefun () и вызванный AutoLISP или acedInvoke (). И acedDefun () и acedRegFunc () передают тот же самый целочисленный функциональный код.

Если зарегистрированная функция должна отыскать параметры, это должно делать так, делая ее собственный запрос к acedGetArgs ().

AcedGetArgs () запрос перемещен, чтобы быть в пределах функционального fact(). Указатель буфера результата rb сделан переменной скорее чем параметр. (Это не соответствует запросу к fact () в 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().

ОБРАТИТЕ ВНИМАНИЕ, вызывает ли приложение acedRegFunc() чтобы регистрировать обработчик для каждой внешней функции, это определяет, это может предполагать, что эти функции будут вызваны acedInvoke(), и это может опустить kInvkSubrMsg случай acrxEntryPoint () функция. Если Вы проектируете приложение, которое требует больше чем единственный файл кода ObjectARX, эта методика предпочтительна, потому что это размещает бремя обработки функции, вызывает ObjectARX библиотеку скорее чем на acrxEntryPoint() функцию.

Если функциональный запрос начинает последовательность запроса, которая заставляет функцию в том же самом приложении быть вызванной с acedInvoke (), последняя функция должна быть зарегистрирована acedRegFunc(). Если вызванная функция не зарегистрирована, acedInvoke () сообщает о ошибке. Следующий рисунок иллюстрирует эту ситуацию:

В иллюстрации выше,

§  A_tan () вызывает B_sin ()

§  A_tan () вызывает C_cos ()

§  B_sin () вызывает A_pi ()

§  C_cos () вызывает A_pi ()

Где приложение A определяет A_tan () и A_pi (), приложение B определяет B_sin (), и приложение C определяет C_cos (). A_pi () функция должен быть зарегистрирован acedRegFunc().

Чтобы предотвращать acedInvoke() от сообщающих ошибок регистрации, регистрируйте любую внешнюю функцию, которая, как предполагается, будет вызвана с acedInvoke().

AcedRegFunc() функция может быть вызван также, чтобы нерегистрировать внешнюю функцию. То же самое приложение должно или регистрировать или нерегистрировать функцию; ObjectARX запрещает приложение от непосредственно управления другим приложением.

Обработка Ошибок от Вызванных Функций

Когда acedInvoke() возвращает RTNORM, это подразумевает, что внешняя функция была вызвана и возвращена успешно. Это не подразумевает, что внешняя функция успешно получила результат; чтобы получить эту информацию, ваша программа должна осмотреть параметр результата. Если внешняя функция успешна и предполагается к возвращаемым значениям, результат указывает на список буфера результата, содержащий один или большее количество значений. Если внешняя функция потерпела неудачу, параметр результата установлен в NULL.

Параметр результата - также NULL, если внешняя функция не возвращает результат.

Следующий типовой кодовый фрагмент проверяет возвращаемое значение внешней функции, которая, как ожидается, возвратится один или большее количество значений результата:

struct resbuf *xfcnlist, *xresults;

// Build the invocation list, xfcnlist.

rc = acedInvoke(xfcnlist, &xresults);

if (rc!= RTNORM) {

// Couldn't call the function—report this error (or even abort).

return BAD;

}

if (xresults == NULL) {

// Function was called but returned a bad result.

return BAD;

}

// Look at return results and process them.

Обработка Внешних Приложений

ObjectARX-приложения могут загружать и разгружать другие ObjectARX-приложения и получать, список которого внешние приложения в настоящее время загружены, также, как программы AutoLISP могут (использование arxloaded). Следующий запрос загружается, программа вызвала myapp:

if (acedArxLoad ("myapp") != RTERROR) {

// Use acedInvoke() to call functions in "myapp".

}

Когда ваша программа закончена с myapp, это может разгрузить это, вызывая

acedArxUnload("myapp");

Функция acedArxLoaded() может использоваться, чтобы получить имена всех в настоящее время загруженных приложений, как в следующем коде:

struct resbuf *rb1, *rb2;

for (rb2 = rb1 = acedArxLoaded(); rb2 != NULL; rb2 = rb2->rbnext) {

if (rb2->restype == RTSTR)

acutPrintf("%s\n", rb2->resval. rstring);

}

acutRelRb(rb1);

Вы можете вызывать функции acedArxLoaded () и acedArxUnload () в конъюнкции друг с другом. Следующий пример разгружает все приложения кроме текущего:

struct resbuf *rb1, *rb2;

for (rb2 = rb1 = acedArxLoaded(); rb2 != NULL; rb2 = rb2->rbnext) {

if (strcmp(ads_appname, rb2->resval. rstring) != 0)

acedArxUnload(rb2->resval. rstring);

}

acutRelRb(rb1);

Переменные, типы и значения, определенные в ObjectARX

ObjectARX определяет несколько типов данных для среды AutoCAD. Это также определяет множество символических кодов для значений, которые пропускают функции (или просто для общей ясности). Наконец, это объявляет и инициализирует несколько глобальных переменных.

Определения и объявления появляются в ObjectARX файлах заголовка.

ОБРАТИТЕ ВНИМАНИЕ, не ли приложение твердо придерживается соглашений, наложенных по определениям и объявлениям, описанным в этой главе, будет трудно читать и поддержать в лучшем; в худшем случае, это не будет связываться с AutoCAD правильно. Также, будущие версии ObjectARX могут вовлекать изменения к файлам заголовка. Поэтому, не замените целочисленную константу на ее символический код, если такой код был определен.

Общие Типы и Определения

Типы и определения, описанные в этой секции обеспечивают последовательность между приложениями и соответствием с требованиями AutoCAD. Они также способствуют четкости приложения.

Вещественные числа

Реальные значения в AutoCAD - всегда с двойной точностью с плавающей точкой значения.

ObjectARX сохраняет этот стандарт, определяя специальный тип ads_real, следующим образом:

typedef double ads_real;

Реальные значения в ObjectARX-приложении имеют тип ads_real.

Точки

Точки AutoCAD определены как следующий тип массива:

typedef ads_real ads_point [3];

Точка всегда включает три значения. Если точка двумерна, третий элемент массива может игнорироваться; самое безопасное инициализировать это к 0.

ObjectARX определяет следующие значения точки:

#define X 0

#define Y 1

#define Z 2

В отличие от простых типов данных (или списки точки в AutoLISP), точка не может быть назначена с единственной{*отдельной*} инструкцией. Чтобы назначать указатель, Вы должны копировать индивидуальные элементы массива, как показано в следующем примере:

newpt [X] = oldpt [X];

newpt [Y] = oldpt [Y];

newpt [Z] = oldpt [Z];

Вы можете также копировать значение точки с ads_point_set () макрокоманда. Результат - второй параметр к макрокоманде.

Следующие типовые кодовые наборы точка, чтобы равняться к сути от:

ads_point to, from;

from[X] = from[Y] = 5.0; from[Z] = 0.0;

ads_point_set(from, to);

ОБРАТИТЕ ВНИМАНИЕ на макрокоманду This, подобно ads_name_set () макрокоманда, определен по-другому, в зависимости от того, действительно ли символ __ STDC __ (для стандарта C) определен.

Стандартная версия C ads_point_set () требует, чтобы ваша программа включила string. h.

Из-за соглашений передачи параметров языка C, точки пропускает ссылка без адреса оператор (косвенности) и. (C всегда передает параметры массива ссылкой, с указателем на первый элемент массива.)

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132