Тема: Не вставить AcDbRasterImageDef в AcDbDictionary

Здравствуйте, знатоки!
До зарезу нужно программно вставить картину в чертеж. Для этого я решил воспользоваться кодом
из SDK samples\misc\ism.
Вот фрагмент функции CustomApplication::createAcDbRasterImageDef из примера:

AcDbRasterImageDef* pAcDbRasterImageDef = new AcDbRasterImageDef;    
pAcDbRasterImageDef->setSourceFileName(parImagePath);
 pAcDbRasterImageDef->load(); 
  DictionaryId = AcDbRasterImageDef::imageDictionary(acdbHostApplicationServices()->workingDatabase());
 if (DictionaryId.asOldId() == 0) 
            AcDbRasterImageDef::createImageDictionary(acdbHostApplicationServices()->workingDatabase(),                 DictionaryId);
acdbOpenObject((AcDbObject*&)pDictionary, DictionaryId, AcDb::kForWrite);
bNameInUse = pDictionary->has(parImageName);
    if (!bNameInUse) 
        ErrorStatus = pDictionary->setAt(parImageName, pAcDbRasterImageDef, parObjectId);
 и т.д.

Код примера проверяю без искажений, только заменил CString'и на  ACHAR'ы. И код мой миксовый.
На строке pDictionary->setAt(....) имею исключение "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Помогите побороть проблему!
Заранее благодарен.

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Начни с того, что проверяй коды возврата функций.

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Это вы верно подметили!
Я проверяю код примера без искажений, а проверку удалил только для краткости на форуме.
вот оригинальный код:

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);
    else
    {
        pDictionary->close();
        delete pAcDbRasterImageDef;
        return Acad::eHandleInUse;
    }
    pDictionary->close();
    pAcDbRasterImageDef->close();
    return ErrorStatus;
}

Беда возникает на ErrorStatus = pDictionary->setAt(...), причем до ErrorStatus даже не доходит. В отладчике удалось прочитать unhandled exception: Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

(изменено: Александр Ривилис, 2 июня 2011г. 14:57:01)

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Надеюсь, что parImageName не 0 и инициализировано правильным адресом, pDictionary != 0 и т.д.

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

да, pDictionary уже не 0 после процедуры acdbOpenObject, и строка ключа parImageName  тоже ненулевая.
Непонятка в основном в следующем: сам примерчик-то из SDK прекрасно компилится и исправно работает! А взятая из него один-в-один функция не пашет. У меня миксовый код, может в этом дело? Или это не влияет?

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Максим Маланичев пишет:

У меня миксовый код, может в этом дело?

Теоретически может. А может ты память рушишь еще где-то раньше, просто exception валится именно в этот момент. И надеюсь, что код у тебя работает в контексте документа (я не увидел в коде блокировки документа).

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Заблокировал, вы сами так на форуме учили:

try{
        AcAxDocLock docLock(acdbHostApplicationServices()->workingDatabase(),AcAxDocLock::kNormal);
  ......................
}catch (const Acad::ErrorStatus){ pDictionary->close(); }
 catch (  Exception ^ e){ 
        ACHAR msg[400];
        this->StringToACHAR(e->Message, msg);        
        acutPrintf(_T("\n   >>>  %s \n "), msg); 
        pDictionary->close();
    }

От себя добавил второй catch (  он-то как раз и срабатывает )
Так хоть на FATAL не выходит, а просто выводит ругань в строку.

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Интересно, а как ты грузишь это приложение в AutoCAD?

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

через netload

Re: Не вставить AcDbRasterImageDef в AcDbDictionary

Правильно.