Extended data (xdata) is created by applications written with ObjectARX ® or AutoLISP ® and can be added to any object. Xdata consists of a linked list of resbufs used by the application. (AutoCAD maintains the information but doesn't use it.) The data is associated with a DXF group code in the range of 1000 to 1071.
This mechanism is space-efficient and can be useful for adding lightweight data to an object. However, xdata is limited to 16K and to the existing set of DXF group codes and types.
For a more detailed description of xdata, see the AutoCAD DXF Reference.
Use the AcDbObject::xData() function to obtain the resbuf chain containing a copy of the xdata for an object:
virtual resbuf* AcDbObject::xData(const char* regappName = NULL) const;
Use the AcDbObject::setXData() function to specify the xdata for an object:
virtual Acad::ErrorStatus AcDbObject::setXData(const resbuf* xdata);
The following example uses the xData() function to obtain the xdata for a selected object and then prints the xdata to the screen. It then adds a string (testrun) to the xdata and calls the setXdata() function to modify the object's xdata. This example also illustrates the use of the upgradeOpen() and downgradeOpen() functions.
// This function calls the selectObject() function to allow // the user to pick an object; then it accesses the xdata of // the object and sends the list to the printList() function // that lists the restype and resval values. // void printXdata() { // Select and open an object. // AcDbObject *pObj; if ((pObj = selectObject(AcDb::kForRead)) == NULL) { return; } // Get the application name for the xdata. // char appname[133]; if (acedGetString(NULL, "\nEnter the desired Xdata application name: ", appname) != RTNORM) { return; } // Get the xdata for the application name. // struct resbuf *pRb; pRb = pObj->xData(appname); if (pRb != NULL) { // Print the existing xdata if any is present. // Notice that there is no -3 group, as there is in // LISP. This is ONLY the xdata, so // the -3 xdata-start marker isn't needed. // printList(pRb); acutRelRb(pRb); } else { acutPrintf("\nNo xdata for this appname"); } pObj->close(); } void addXdata() { AcDbObject* pObj = selectObject(AcDb::kForRead); if (!pObj) { acutPrintf("Error selecting object\n"); return; } // Get the application name and string to be added to // xdata. // char appName[132], resString[200]; appName[0] = resString[0] = '\0'; acedGetString(NULL, "Enter application name: ", appName); acedGetString(NULL, "Enter string to be added: ", resString); struct resbuf *pRb, *pTemp; pRb = pObj->xData(appName); if (pRb != NULL) { // If xdata is present, then walk to the // end of the list. // for (pTemp = pRb; pTemp->rbnext != NULL; pTemp = pTemp->rbnext) { ; } } else { // If xdata is not present, register the application // and add appName to the first resbuf in the list. // Notice that there is no -3 group as there is in // AutoLISP. This is ONLY the xdata so // the -3 xdata-start marker isn't needed. // acdbRegApp(appName); pRb = acutNewRb(AcDb::kDxfRegAppName); pTemp = pRb; pTemp->resval.rstring = (char*) malloc(strlen(appName) + 1); strcpy(pTemp->resval.rstring, appName); } // Add user-specified string to the xdata. // pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString); pTemp = pTemp->rbnext; pTemp->resval.rstring = (char*) malloc(strlen(resString) + 1); strcpy(pTemp->resval.rstring, resString); // The following code shows the use of upgradeOpen() // to change the entity from read to write. // pObj->upgradeOpen(); pObj->setXData(pRb); pObj->close(); acutRelRb(pRb); }