Списки и другие динамически размещенные данные
Структура resbuf включает поле указателя, rbnext, для соединения буферов результатов в список. Буфера Результатов могут быть размещены статически, объявляя их в приложении. Вы делаете это, когда только единственный буфер результатов используется (например, acedGetVar () и acedSetVar ()) или когда, только короткий список необходим. Но более длинные списки проще, чтобы обработать, размещая их динамически, и списки, возвращенные функциями ObjectARX всегда размещаются динамически. Один из наиболее часто используемые функции, который возвращает список связей - acedGetArgs ().
“ Оценка Внешних Функций ” на странице 526 показывает AutoLISP, запрашивающий внешней подпрограммы, которая берет параметры трех отличных типов: строка, целое число, и реальное значение:
( Doit pstr iarg rarg)
Следующий код сегментирует показы, как осуществить функцию с такой последовательностью запроса. Типовая функция проверяет, чтобы список параметров был правилен и сохранил значения в местном масштабе перед действием на них (операции не показываются). Пример предполагает, что предыдущий запрос к acedDefun () назначил внешнюю подпрограмму функциональный код 0, и что все функции, определенные этим приложением берут по крайней мере один параметр:
// Выполнить определенную функцию.
int dofun()
{
struct resbuf *rb;
char str[64];
int ival, val;
ads_real rval;
ads_point pt;
// Get the function code.
if ((val = acedGetFuncode()) == RTERROR)
return BAD; // Indicate failure.
// Get the arguments passed in with the function.
if ((rb = acedGetArgs()) == NULL)
return BAD;
switch (val) { // Which function is called?
case 0: // (doit)
if (rb->restype != RTSTR) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a string.");
return BAD;
}
// Save the value in local string.
strcpy(str, rb->resval.rstring);
// Advance to the next result buffer.
rb = rb->rbnext;
if (rb == NULL) {
acutPrintf("\nDOIT: Insufficient number of arguments.");
return BAD;
}
if (rb->restype != RTSHORT) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a short integer.");
return BAD;
}
// Save the value in local variable.
ival = rb->resval.rint;
// Advance to the last argument.
rb = rb->rbnext;
if (rb == NULL) {
acutPrintf("\nDOIT: Insufficient number of arguments.");
return BAD;
}
if (rb->restype != RTREAL) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a real.");
return BAD;
}
// Save the value in local variable.
rval = rb->resval.rreal;
// Check that it was the last argument.
if (rb->rbnext != NULL) {
acutPrintf("\nDOIT: Too many arguments.");
return BAD;
}
// Operate on the three arguments.
. . .
return GOOD; // Indicate success
break;
case 1:
// Execute other functions.
. . .
}
}
ОБРАТИТЕ ВНИМАНИЕ, что этот пример исключителен в одном отношении: acedGetArgs () - единственная ObjectARX глобальная функция, которая возвращает список связей, который приложение должно явно не выпустить. Следующая секция описывает обычный путь управления памятью, необходимой для списков.