odgsinitialize() throwing exception
odgsinitialize() throwing exception
hi,
i am moving from dwgdirect 2.2.0 to 2.6.3. i could compile the project properly using the static libs. but there is a problem with odgsinitialize() call.
in my app if i can open a file properly but opening any other file (keeping previous file open) is crashing as an exception is thrown from odgsinitialize() and subsequent calls are not being made because of that, and it is causing a crash as some point.
following is the call stack when exception is thrown
226c67ac()
dxfdwg.aip!odsmartptr<odrxsystemservices>::interna laddref() + 0x20 bytes
dxfdwg.aip!odsmartptr<odrxsystemservices>:

dsmart ptr<odrxsystemservices>() + 0x24 bytes
dxfdwg.aip!odrxdynamiclinkerimpl::sysservices() + 0x1f bytes
dxfdwg.aip!odrxsystemservices() + 0x3e bytes
dxfdwg.aip!odrxdynamiclinkerimpl::loadmodule() + 0x111 bytes
dxfdwg.aip!odrxloadmoduleinternal() + 0x44 bytes
dxfdwg.aip!odrxloadgsmoduleinternal() + 0x47 bytes
dxfdwg.aip!odgsinitialize() + 0x11 bytes
> dxfdwg.aip!dxfdwgplugin::goimportfile(aifileformat message * message=0x0013dc80) line 736 c++
dxfdwg.aip!dxfdwgplugin::gofileformat(aifileformat message * message=0x0013dc80) line 1157 + 0xc bytes c++
following is my code.
aserr dxfdwgplugin::goimportfile(aifileformatmessage *message)
{
#if !defined(_toolkit_in_dll_) || defined(__mwerks__)
odrx_init_static_module_map();
#endif
aierr err = knoerr;
// create a custom services object.
odrxobjectimpl<myservices> svcs;
odinitialize(&svcs);
odgsinitialize();
std::auto_ptr<importpreferences> pref(importpreferences::getinstance());
try
{
filestream fs(message->getfilepath());
// initialize character mapper
if (!svcs.initializeodcharmapper())
{
throw dxfdwgexception(dxfdwgexception::edxfdwgcharmapper notinitialized);
}
// create a database and load the drawing into it.
oddbdatabaseptr pdb = svcs.readfile(&fs, true /* force character conversions */);
if (!pdb.isnull())
{
pref->getpreferencesfromfile();
oddbobjectid layoutid;
ai::unicodestring selectedlayoutname;
pref->getselectedlayoutname(selectedlayoutname);
if (!selectedlayoutname.empty())
{ // a specific layout is set to be imported, get its id.
oddbdictionaryptr playoutdic = pdb->getlayoutdictionaryid().safeopenobject();
// search thru all layout names
for (oddbdictionaryiteratorptr playoutiter = playoutdic->newiterator();
!playoutiter->done();
playoutiter->next())
{
ai::unicodestring layoutname;
utils:

dstring2aiunicode(playoutiter->name(), layoutname);
if (selectedlayoutname == layoutname)
{ // layout names match
layoutid = playoutiter->objectid();
break;
}
}
}
if (layoutid.isnull())
{
layoutid = pdb->currentlayoutid();
}
// begin vectorization.
// create the vectorization context.
odgicontextfordbdatabaseptr pdwgcontext = odgicontextfordbdatabase::createobject();
// create the custom rendering device.
odgsdeviceptr pdevice = exgssimpledevice::createobject();
// set the database to be vectorized.
pdwgcontext->setdatabase(pdb);
// prepare the device to render the user chosen layout in this database.
pdevice = oddbgsmanager::setuplayoutviews(layoutid, pdevice, pdwgcontext);
// initiate vectorization.
pdevice->update();
// end vectorization.
}
}
catch (const dxfdwgexception& e)
{
}
catch (const oderror& error)
{
}
odgsuninitialize();
oduninitialize();
return err;
}
what might have gone wrong?
last edited by
harshv@adobe.com; 1st october 2008 at 03:50 amfff">.
what do you mean by "keeping previous file open" - as far as i can see, you open the file, render it, and exit the function. or you are running 2 such functions in parallel threads?
vladimir
means i am not unloading the library. this problem wasn't in version 2.2.0
i can't reproduce it.
perhaps you can modify e.g. odvectorizeex sample, to demonstrate the behaviour?
(i've no idea what may have changed - perhaps you store some smart pointer somewhere?)
vladimir
it is throwing exception while odgsinitialize() is being called as you can see in the stack trace where it is throwing exception. any guesses what may cause odgsinitialize() to throw exception?
it looks like when oduninitialize() is called, there are still references to dd (some stray smart pointers perhaps). if there a re references - dynamic linker object is not destroyed. but, system services object gets destroyed (because it is declared static), and the pointer to it is still stored in dynamic linker. when next odinitialize is called, dynamic linker object do not reinitialize, because it is still referenced - it just increases reference counter.
then, while in odgsinitialize() an attempt is made to load gs module - it acceesses erased system services object and fails.
you may check if dynamic linker is zero after oduninitialize() - call odrxdynamiclinker()
vladimir
last edited by vkalinin; 2nd october 2008 at 07:33 amfff">.
no it is not zero after the call. is there a way to check which pointers are left stray and might be causing problem?
last edited by
harshv@adobe.com; 20th october 2008 at 02:52 amfff">.
usually such errors show up at exit.
perhaps you can manually release dynamic linker object (call odrxdynamiclinker()->release()), and then you will get a crash in the stray object destructor, at the application exit. this should show the type of the object
vladimir
i found the cause of the problem.
it happened because, inside vectorization process i.e. after call of exgssimpledevice::update() i had called
cautocaddrawing::getinstance(), just to get the approximate number of objects in the the database on this instance. and didn't release it afterward. removing this solved the problem. now i am getting the approximate number of objects using the call.
(dynamic_cast<oddbdatabase*>(context()->database()))->approxnumobjects()
thanks,
harsha