Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have the same code in C++ and C# for ArcMap. This code loads a document from disk and trying to get a picture for PictureSimbol object. But in case of C++ error occurs(HRESULT = E_UNEXPECTED 0x8000ffff). C# code works without any problem. Why such a difference may occur? (mxd_file_name the same in both cases)

C++ code

esriCarto::IMapDocumentPtr map_doc(esriCarto::CLSID_MapDocument);
map_doc->Open(mxd_file_name, L"");
esriCarto::IMapPtr mp = map_doc->Map[0];
esriCarto::IFeatureLayerPtr layer = mp->Layer[0];
esriCarto::ILegendInfoPtr inf = layer;
esriCarto::ILegendGroupPtr gr = inf->GetLegendGroup(0);
esriCarto::ILegendClassPtr cl = gr->Class[0];
esriDisplay::ISymbolPtr s = cl->Symbol;
esriDisplay::IMultiLayerFillSymbolPtr mls = s;
esriDisplay::IFillSymbolPtr fs = mls->Layer[0];
esriDisplay::IPictureFillSymbolPtr pfs = fs;

IPictureDisp * pic = 0;
HRESULT hr = pfs->get_Picture(&pic); // hr = E_UNEXPECTED 0x8000ffff catastrophic failure
map_doc->Close();

C#

ESRI.ArcGIS.Carto.IMapDocument map_doc = new ESRI.ArcGIS.Carto.MapDocument();
map_doc.Open(mxd_file_name);
ESRI.ArcGIS.Carto.IMap mp = map_doc.Map[0];
ESRI.ArcGIS.Carto.IFeatureLayer layer = mp.Layer[0] as ESRI.ArcGIS.Carto.IFeatureLayer;
ESRI.ArcGIS.Carto.ILegendInfo inf = layer as ESRI.ArcGIS.Carto.ILegendInfo;
ESRI.ArcGIS.Carto.ILegendGroup gr = inf.LegendGroup[0];
ESRI.ArcGIS.Carto.ILegendClass cl = gr.Class[0];
ESRI.ArcGIS.Display.ISymbol s = cl.Symbol;
ESRI.ArcGIS.Display.IMultiLayerFillSymbol mls = s as ESRI.ArcGIS.Display.IMultiLayerFillSymbol;
ESRI.ArcGIS.Display.IFillSymbol fs = mls.Layer[0];
ESRI.ArcGIS.Display.IPictureFillSymbol pfs = fs as ESRI.ArcGIS.Display.IPictureFillSymbol;
stdole.IPictureDisp pic = pfs.Picture; // works fine
map_doc.Close();

Update: There is no problem with IPictureDisp * pic = 0; Actually I just paste code for IPictureDispPtr pic = pfs->GetPicture() because I do not want an exception instead of error HRESULT. Bellow is an autogenerated code for GetPicture function

inline IPictureDisp * IPictureFillSymbol::GetPicture ( ) {
    IPictureDisp * _result = 0;
    HRESULT _hr = get_Picture(&_result);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _result;
}

C++ code works, if the map is not taken from hard drive but obtained from the same document that loaded in ArcMap. Here's the code:

esriArcMapUI::IMxDocumentPtr document(application_->Document); // application_ is the ArcMap application
esriCarto::IMapPtr mp = document->Maps->Item[0];
// the rest code is unchanged
esriCarto::IFeatureLayerPtr layer = mp->Layer[0];
esriCarto::ILegendInfoPtr inf = layer;
esriCarto::ILegendGroupPtr gr = inf->GetLegendGroup(0);
esriCarto::ILegendClassPtr cl = gr->Class[0];
esriDisplay::ISymbolPtr s = cl->Symbol;
esriDisplay::IMultiLayerFillSymbolPtr mls = s;
esriDisplay::IFillSymbolPtr fs = mls->Layer[0];
esriDisplay::IPictureFillSymbolPtr pfs = fs;

IPictureDisp * pic = 0;
HRESULT hr = pfs->get_Picture(&pic); // same code works fine
map_doc->Close();
share|improve this question
1  
Esri's doc on smart types says: "Beware! Don't use the & operator to pass data. Instead, put your smart pointer in a container structure and pass the address of the container structure." –  Kirk Kuykendall May 19 '11 at 16:06
    
@Kirk - I expanded my question with pointer stuff –  Oleg Svechkarenko May 19 '11 at 16:58

2 Answers 2

This line here may be the issue.

esriDisplay::IPictureFillSymbolPtr pfs = fs;

You're accessing the method:

get_Picture(&pic)

using pointer notation, but not declaring as a pointer.

try:

...
esriDisplay::IPictureFillSymbolPtr *pfs = fs;

IPictureDisp * pic = 0;
HRESULT hr = pfs->get_Picture(&pic);
...

Let us all know if it works.

Cheers

share|improve this answer
    
It is not the problem. C++ code works fine, if the map is not taken from hard drive (via IMapDocument.Open) but obtained from the same document that loaded in ArcMap (via IApplication.Document as IMxDocument) –  Oleg Svechkarenko May 19 '11 at 16:09
up vote 1 down vote accepted

The problem was that the c++ code runs in a separate thread and this thread hasn't a CoInitialize call. After adding this call (+ CoUnitialize) to the thread function the problem disappeared.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.