Techniques for Avoiding Trouble

from the official adesk ads documentation

Passing Pointers Instead of Data Structures

One frequent problem of programming with ADS is due to the large number of library functions that pass their results by reference. In all such cases, the application must define an argument of the appropriate size and type. It is tempting to define the argument as a pointer to the correct type , b ut this causes the library function to return garbage data, and can cause other data in memory to be corrupted . T he mistake is illustrated by ads_getangle() in the following function fragment:
int thing()
{
 ads_real *result; /* Only allocates space for pointer */
 ads_point pt;

 pt[X] = .;
 pt[Y] = .;
 pt[Z] = .;

 if (ads_getangle(pt, "Enter desired angle: ", result)
  != RTNORM)
  return BAD;
 . 
 . 
 .
}
The result argument should be declared as ads_real , as shown here in the corrected version .
int thing()
{
 ads_real result; /* Allocates space for real number */
 ads_point pt;

 pt[X] = .;
 pt[Y] = .;
 pt[Z] = .;

 if (ads_getangle(pt, "Enter desired angle: ", &result) != RTNORM)
  return BAD;
 .
 .
 .
}
As the preceding e xample shows, the mistake can be hard to catch because the error is mainly in the argument declaration and not in the function call as such ; t he giveaway is the absence of the address operator & . The problem becomes harder to see when the result argument is a string or an array (such as ads_point ), because string and array names are already pointers a nd do not require the & operator. The mistake is illustrated here by ads_rtos() .
char *rlstr; /* Allocates only the pointer */
ads_real dist;

dist = ads_rtos(dist, rlstr);  /* WRONG!! */
This does not provide enough space for the result buffer. A correct way to declare the buffer and call ads_rtos() is shown by the next excerpt .
char rlstr[13]; /* Allocates room for the string */
ads_real dist;

dist = ads_rtos(dist, rlstr);
If the application seems to be working with garbled data, check the declarations of variables used as result arguments in calls to the ADS library.

Failing to Free Selection Sets

One of the most insidious errors that a n ADS application can make is failing to release the selection sets it creates with calls to ads_ssget() and ads_ssadd() ; e ach call that creates a new selection set must be matched by a call to ads_ssfree() . AutoCAD permits only a limited number of selection sets to be open at a given time (it does n't m atter whether or not the selection set contains entities ) . If you forget to use ads_ssfree() to free a selection set, you use u p one of this limited number of sets. Sooner or later, the application will run out of selection sets and ads_ssget() operations will fail without apparent reason. Even worse, the ads_ssget() call that fails may be unrelated to the command that is losing selection sets , and may in fact b e in a different application. If your application runs for a while and then fails, but starts to work again after you restart AutoCAD, f ailure to release selection sets with ads_ssfree() is most likely t he cause. Carefully read code that handles selection sets , and make sure that every selection set obtained is eventually released by a call to ads_ssfree() . Pay special attention to error-handling code . Wh en you write c ode that returns under error conditions, it is easy to forget to release all selection sets that are open. If ads_ssget() reports an error (that is, if it does not return RTNORM ), it does not create a new selection set, so you don't have to release the specified selection set name. The same applies to ads_ssadd() when it is called with null pointers to create a new selection set.

Failing to Use Long Integers as Selection S et Indexes

Because AutoCAD selection sets can contain more than 65,535 entities, the selection s et indexes used in the ads_sslength() and ads_ssname() functions are of the type long . Because s ome implementations of C treat the int type as 16 bits, equivalent to a short , it is essential that you declare the variables used with these functions as long . Special caution is required when you are d eveloping an ADS application on a system (including many UNIX systems) on which the int and long types are identical . If you inadvertently declare a selection s et index as an int and you later port it to a short integer system (such as OS/2), y our application will fail in obscure ways . For the same reasons, if you use a constant in a call to ads_ssname() , pass it as a long value by appending an L to the value ( as in 112L ). (Standard C compilers correctly promote 16-bit integers to long s, but this can cause problems if you recompile your application using an older version of C.)

Failing to Release Result Buffers

Several ADS functions dynamically allocate storage for results they return. Your application should release these buffers with calls to ads_relrb() or free() , as appropriate. A program that fails to release result buffers will appear to be working properly but will eventually run out of memory, causing symptoms that may a ppear long after the storage was lost. Also, the performance of AutoCAD can be affected even after the application has been unloaded. Pay particular attention to code that uses result buffers, and verify that all paths following the allocation of a buffer end in its release. Also, note that ads_getvar() , which is passed a static result buffer, dynamically allocates a buffer to return results of type RTSTR ; t his string must be released with a call to free() .

Opening Files in Shared Mode

When AutoCAD and AutoLISP access files, they do so in an exclusive mode to prevent other programs from tampering with a file's contents while it is being read or written. Your ADS applications should do the same. They should never open files in a shared mode for either reading or writing. This is especially important when your application is accessing files that belong to AutoCAD. If you open an AutoCAD file using a shared mode, AutoCAD cannot access it and may h ang. Even if the file is not an AutoCAD file, using a shared mode can lead to conflicts with other applications that access the same file. Problems that arise from this situation can be difficult to trace, especially in a network environment. The details of how to ensure that your application has exclusive access to an open file vary from platform to platform. Your system's documentation should explain how to do this. Also , check the platform-specific on-line documents shipped with AutoCAD to see if they contain advice about how to open and close files.