本文迁移自本人网易博客,写于2013年1月5日,未处理的非法访问读异常(插入影像图代码) - lysygyy的日志 - 网易博客 (163.com)
Acad::ErrorStatus CustomApplication::createAcDbRasterImageDef (AcDbObjectId & parObjectId,
ACHAR * parImageName, ACHAR * parImagePath)
{
// declaration
Acad::ErrorStatus ErrorStatus;
AcDbObjectId DictionaryId;
AcDbDictionary* pDictionary;
Adesk::Boolean bNameInUse;
// Create new image def object
AcDbRasterImageDef* pAcDbRasterImageDef = new AcDbRasterImageDef;
if (pAcDbRasterImageDef == NULL)
return Acad::eNullObjectPointer;
ErrorStatus = pAcDbRasterImageDef->setSourceFileName(parImagePath);
if (ErrorStatus != Acad::eOk)
{
ads_printf(_T("Error: Could not find the image file.\n"));
delete pAcDbRasterImageDef;
return ErrorStatus;
}
ErrorStatus = pAcDbRasterImageDef->load();
if (ErrorStatus != Acad::eOk)
{
ads_printf(_T("Error: Could not open the image file.\n"));
delete pAcDbRasterImageDef;
return ErrorStatus;
}
DictionaryId = AcDbRasterImageDef::imageDictionary(acdbHostApplicationServices()->workingDatabase());
if (DictionaryId.asOldId() == 0)
{
ErrorStatus = AcDbRasterImageDef::createImageDictionary(acdbHostApplicationServices()->workingDatabase(), DictionaryId);
if (ErrorStatus!= Acad::eOk)
{
delete pAcDbRasterImageDef;
return ErrorStatus;
}
}
ErrorStatus = acdbOpenObject((AcDbObject*&)pDictionary, DictionaryId, AcDb::kForWrite);
if (ErrorStatus != Acad::eOk)
{
delete pAcDbRasterImageDef;
return ErrorStatus;
}
bNameInUse = pDictionary->has(parImageName);
if (!bNameInUse)
ErrorStatus = pDictionary->setAt(parImageName, pAcDbRasterImageDef, parObjectId); //这一行时崩溃,unhandled access violation reading 0x0054 exception at 64554c66h
else
{
pDictionary->close();
delete pAcDbRasterImageDef;
return Acad::eHandleInUse;
}
pDictionary->close();
pAcDbRasterImageDef->close();
return ErrorStatus;
}
查了两天,最终发现问题在于:加载影像图之前必须先加载模块 acismobj17.dbx,而我原来的工程中可能是加载其他模块时将该模块自动加载了,另外Autocad自带的附着图像功能也将该模块加载进去了,命令 imageAttach,回车,弹出选择文件对话框之前,就先加载了两个模块: acismobj17.dbx 和 acismui.arx。所以在测试的时候只要选了附着图像的命令,再调用我的自定义命令,就不会出错了。