找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1002|回复: 5

[ARX程序]:程序执行时,AutoCAD报错(严重死掉),原因未明,请前辈指点!

[复制链接]
发表于 2004-6-24 17:38:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本程序在编译时通过, 但AutoCAD里运行命令时,会出现错误, 现原因未明, 而且应有很多要修改的地方,恳请前辈们指正, 修改 .

//=======================
//程序功能: 遍历指定层上的所有圆, 并在新建一个层, 在圆心位置用文本对圆进行编号!
//=======================

void corillasetcircnum()
{

        char LayerName[15];                                                //层名变量       
        AcDbDatabase *pDb = NULL;                                //数据库指针
        AcGePoint3dArray *pCircCenter = NULL;        //圆心坐标数组指针

       
        pDb = acdbHostApplicationServices()->workingDatabase();                //取得库指针
       
        acedGetString(1,"\n请输入要编号的圆所在的层名:",LayerName);               

//===========遍历指定层上的所有圆,并取和圆心==========

        AcDbBlockTable *pBlockTable;
        pDb->getSymbolTable(pBlockTable, AcDb::kForRead);
       
        AcDbBlockTableRecord *pBlockTableRecord;
        pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
        pBlockTable->close();
       
        AcDbBlockTableRecordIterator *pIterator;
        pBlockTableRecord->newIterator( pIterator);
       
        for( ; !pIterator->done(); pIterator->step())                //遍历开始
        {
               
                AcDbEntity *pEnt;
                AcDbCircle *pCirc;
               
                pIterator->getEntity(pEnt,AcDb::kForRead);
               
                if( strcmp(pEnt->layer(),LayerName) && pEnt->isKindOf( AcDbCircle::desc())) //过滤指定层并是圆实体
                {
                        pCirc = AcDbCircle::cast(pEnt);
                        pCircCenter->append(pCirc->center());        //追加圆心到AcGePoint3dArray指针变量
                       
                }
                pEnt->close();
                pCirc->close();
        }
       
        delete pIterator;
        pBlockTableRecord->close();
       
//==================新建一个层并指定为当前层================
       
        AcDbLayerTable *pLayerTable;
        pDb->getSymbolTable(pLayerTable, AcDb::kForWrite);
       
        AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;        //新建一个层记录指针
        pLayerTableRecord->setName("SetNum");
//        pLayerTableRecord->color(NewColor);
       
        AcDbObjectId LayerId;
        pLayerTable->add(LayerId,pLayerTableRecord);
        pDb->setClayer(LayerId);                                                //把新建层高为当前层
       
        pLayerTable->close();
        pLayerTableRecord->close();
       
//================在圆心数组坐标位置上添加文本纺号==============
       
        for(int i=0; i<=pCircCenter->length(); i++)
        {
               
                acedCommand(RTSTR,"TEXT",RT3DPOINT,pCircCenter,RTSHORT,i++,RTSTR,"",RTNONE);
               
        }

}

本程序全没有用上错误语句检测,一来我是新手,前不太熟悉那些错误检测的语法,二来,抱着速度第一的思想,因为,这些程序是雏形,以后等自己能熟练地用这门语言,还得把这些程序写得完整完美!!!!

在这再次感谢热心帮助小弟的前辈们,希望以后更多的指点,小弟感激不尽......
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-6-24 19:33:34 | 显示全部楼层
pCirc = AcDbCircle::cast(pEnt);
这一句可能有问题
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-6-24 19:59:33 | 显示全部楼层
void corillasetcircnum()
{

char LayerName[15]; //层名变量
AcDbDatabase *pDb = NULL; //数据库指针

Error 1
AcGePoint3dArray *pCircCenter = NULL; //圆心坐标数组指针
[/COLOR]

---------correct>>>
AcGePoint3dArray  pCirCenter= new AcGePoint3dArray;   
      // you have to delete it at last.

-------------or >>
AcGePoint3dArray  CirCenter;
     // but you now have to use dot '.' ( instead of '->') to operate it
[/COLOR]


pDb = acdbHostApplicationServices()->workingDatabase(); //取得库指针

acedGetString(1,"\n请输入要编号的圆所在的层名:",LayerName);

//===========遍历指定层上的所有圆,并取和圆心==========

AcDbBlockTable *pBlockTable;
pDb->getSymbolTable(pBlockTable, AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();

AcDbBlockTableRecordIterator *pIterator;
pBlockTableRecord->newIterator( pIterator);

for( ; !pIterator->done(); pIterator->step()) //遍历开始
{

AcDbEntity *pEnt;
AcDbCircle *pCirc;

pIterator->getEntity(pEnt,AcDb::kForRead);


//Error 2:
if( strcmp(pEnt->layer(),LayerName) && pEnt->isKindOf( AcDbCircle::desc())) //过滤指定层并是圆实体
[/COLOR]

----------->Correct
char  *tmp;
int       k;

tmp = pEnt->layer();
k= stricmp(tmp, LayerName);   // you ought to use stricmp(), instead of strcmp()
acutDelString(tmp);  // to see also at last, pls

if( k==0  && pEnt->isKindOf( AcDbCircle::desc())) //过滤指定层并是圆实体
[/COLOR]
{
pCirc = AcDbCircle::cast(pEnt);
pCircCenter->append(pCirc->center()); //追加圆心到AcGePoint3dArray指针变量

}
pEnt->close();
pCirc->close();
}

delete pIterator;
pBlockTableRecord->close();


//==================新建一个层并指定为当前层================

AcDbLayerTable *pLayerTable;
pDb->getSymbolTable(pLayerTable, AcDb::kForWrite);

AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord; //新建一个层记录指针
pLayerTableRecord->setName("SetNum");
// pLayerTableRecord->color(NewColor);

AcDbObjectId LayerId;
pLayerTable->add(LayerId,pLayerTableRecord);
pDb->setClayer(LayerId); //把新建层高为当前层

pLayerTable->close();
pLayerTableRecord->close();

//================在圆心数组坐标位置上添加文本纺号==============

for(int i=0; i<=pCircCenter->length(); i++)
{


//Error 3
acedCommand(RTSTR,"TEXT",RT3DPOINT,pCircCenter,RTSHORT,i++,RTSTR,"",RTNONE);
[/COLOR]


---------Correct
acedCommand(RTSTR,"TEXT",RT3DPOINT,pCircCenter,
RTSTR, "3" /*text height*/, RTSTR, "0" /*Text angle*/,
RTSHORT,i++,RTNONE);
[/COLOR]

}

}

================================================
For Ref. only

  1. AcDbEntity::layer Function char *

  2. layer() const;

  3. This function returns a copy of the name string in the
  4. AcDbLayerTableRecord object referenced by the entity.
  5. [COLOR=Red]
  6. The calling application is responsible for deallocating the memory used by
  7. the returned string. The acutDelString() function is recommended.
  8. [/COLOR]
  9. Warning Calling this function before the entity has had its referenced layer
  10. object ID set (that is, it’s still set to AcDbObjectId::kNull) will terminate
  11. AutoCAD. If the referenced layer objectId is AcDbObjectId::kNull when
  12. the entity is added to a database, it will be set to the object ID of the
  13. database’s current default layer.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-6-25 11:20:33 | 显示全部楼层
谢谢各楼的热心,特谢ishou前辈,让我得益不少!!
程序我已经改正过来,但还是有问题:
经多少修改测试,如果把后面 for() 我这段循环注释掉,命令执行时,AutoCAD不会报错!

如果把acedCommand(RTSTR,"TEXT",RT3DPOINT,pCircCenter,RTSHORT,i++,RTSTR,"",RTNONE);
改为:
acedCommand(RTSTR,"TEXT",RTSTR,"30,30" /* , RT3DPOINT,pCircCenter  */  ,RTSHORT,i++,RTSTR,"",RTNONE);

当然图上我只画一个圆实体了!
就是说,文本的坐标换成指定写入,执行命令没有没有任何报错,正常!
我想,问题应出在, AcGePoint3dArray  arrCircCenter;  (我改后的变量)
这个arrCircCenterd在追加圆心坐标,和最后的acedCommand()输入文本时语法格式是否正确的问题上!!

再验证,我在for()前添加了一个已经初始化的点,AcGePoint3d ptCenter=(10.0, 10.0, 10.0);改后为:

//================在圆心数组坐标位置上添加文本纺号==============
AcGePoint3d ptCenter(10.0,10.0,10.0);
for(int i=0; i<=nCircCenter.length(); i++)
{
               
acedCommand( RTSTR,"TEXT",RT3DPOINT,ptCenter,
                         RTSTR,"3",RTSTR,"0",RTSHORT,i++,RTNONE);
}

这样,程序还是会报错,由于我把这程序注释掉,程序执得时并不报错(上文说得很清楚),
所以本人猜测问题应就出在这个aecdCommand的语法格式上, 输入文本时,应不能输入RT3DPOINT,这个变量类型的!

请前辈指点一下,当然我会去进修,查找资料!!!

============第二次添加=================

AcDbText::AcDbText 函数

AcDbText(

const AcGePoint3d& position,
const char* text,
AcDbObjectId style = AcDbObjectId::kNull,
double height = 0,
double rotation = 0);

position  输入文本插入点
text  输入文本字符串
style  输入要使用的
AcDbTextStyleTableRecord 的对象ID
height   输入形的高度
rotation  输入旋转角

从参数上看,明明是有AcGePoint3d变量的,晕~~~~~~~~~
但为什么:
AcGePoint3d ptCenter(10.0,10.0,0.0);
acedCommand(RTSTR,"TEXT",RT3DPOINT,ptCenter,RTSTR,"5",RTSTR,"0",RTSHORT,i++,RTNONE);

执行这个命令时都会报错!!!编译通过!!!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-6-25 18:49:34 | 显示全部楼层
acedCommand(RTSTR,"TEXT",RT3DPOINT,asDblArray(ptCenter),RTSTR,"5",RTSTR,"0",RTSHORT,i++,RTNONE);

点要这样用:asDblArray(ptCenter),或者用ads_point
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-6-26 15:19:15 | 显示全部楼层
谢谢上楼的帮助,问题我自己已经解决了.

由于点为数组类型,所以要取得数组的头地址,如下:

aecdCommand( RTSTR, "TEXT", RT3DPOINT, &arrPoints, RTSTR, .........., i++, .....)

只在要点数组变量前, 加上一个取址符号 " &" 就行了!!!

同时改一点错误:

上面的命令中的 i++, 应改为  i  , 因为for循环中已经有i++
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-4 04:35 , Processed in 0.380260 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表