来自ObjectARX参考指南
拓展数据(xdata)是ObjectARXhuoAutoLisp应用程序创建的,它可以被加入到任何对象中。xdata由应用程序使用的resbufs链表组成。(AutoCAD保存它但并不会使用它)拓展数据关联1000带1071范围内的拓展数据group code。
这是种节省空间(space-efficient)的机制,向对象添加轻量级别数据十分有效。但是,xdata数据不能超过16kb,同事,也仅限于使用已存在的DXF组编码值和类型。
获取某对象的xdata数据的拷贝resbuf链表的方法是使用AcDbObject::xData:
virtual resbuf*
AcDbObject::xData(const char* regappName = NULL) const;
设置某个对象的xdata,使用AcDbObject::setXData():
virtual Acad::ErrorStatus
AcDbObject::setXData(const resbuf* xdata);
下面的示例使用xData()函数获取所选对象的xData,然后将xData打印到屏幕上。然后,它向xdata添加一个字符串(testrun)并调用setXdata()函数来修改对象的xdata。这个示例还演示了upgradeOpen()和downgradeOpen()函数的使用。
// 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);
}