QA: I cannot use COM objects using #import because _com_issue_error function is undefined. How can I fix it?
October 28th, 2004 by Vassili Philippov
Question
When I use #import directive I get the following compile error: error C2065: ‘_com_issue_errorex’ : undeclared identifier. The same code works OK on PC. Can I use smart pointers and #import directive on Pocket PC? How can I use them?
Answer
_com_issue_error and _com_issue_errorex functions that are used in smart pointers are not defined in eVC++. You should define them yourself or use STUtil library that defines them. These functions are not defined because they use C++ exceptions that are not supported in eVC++.
Smart pointers uses exceptions to inform about error HRESULT return code. Method of smart pointer are wrappers to corresponding methods of wrapped COM interface like:
inline _bstr_t IConverter::IntToString ( int nValue ) {
BSTR _result;
HRESULT _hr = raw_IntToString(nValue, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(_result, false);
}
This method was defined in IDL as
HRESULT IntToString([in] INT nValue, [out, retval] BSTR *pResult);
As we see the method of the smart pointer return value of the [retval] parameter. But return value was used for error information. Smart pointers uses _com_issue_errorex function that throws C++ exceptions.
Using STUtil library
- Download STUtil library and add STUtil.h and STUtil.cpp files into your project.
- Add include of STUtil.h file into Stdafx.h file.
- Use smart pointers. Smart pointers will throw exceptions that could be caught by __except (CATCH_COM_ERROR) code.
- Check COM error code by using GetComError() function that returns CSTComError object.
- If you want ignore COM error define ST_IGNORE_COM_EXCEPTIONS macro (using #define ST_IGNORE_COM_EXCEPTIONS) in your Stdafx.h file. In that case no exception will be thrown, all COM error codes will be ignored.
Source code
Here is a sample code that uses exceptions.
In StdAfx.h file:
#include "STUtil.h"
In custom .cpp code:
IConverterPtr cnv;
_bstr_t str;
__try {
cnv.CreateInstance(_T("Test.Converter"));
str = cnv->IntToString(46);
}
__except (CATCH_COM_ERROR) {
switch (GetComError().Error()) {
case E_FAIL:
::AfxMessageBox(_T("E_FAIL"));
break;
case E_INVALIDARG:
::AfxMessageBox(_T("E_InvalidArg"));
break;
}
}
Here is a sample code that doesn’t use exceptions (ignores COM errors).
In StdAfx.h file:
#define ST_IGNORE_COM_EXCEPTIONS
#include "STUtil.h"
In custom .cpp code:
IConverterPtr cnv(_T("Test.Converter"));
_bstr_t str = cnv->IntToString(46);
