c++ defining function using #define macro to check com result

6.3k Views Asked by At

So I'm working on a windows application and I've decided to write several helper functions to check the HRESULT returned by any com-related function when it is called. I'm trying to define those functions into a macro #define block but I'm really not sure what is the proper syntax. Here are two functions in #define block and the second one gives compiler error when other parts of my program calls it.

#ifndef COMUTILITIES
#define COMUTILITIES
#include <sstream>
#include <fstream>
#include <string>
#include <comdef.h>
#include <AtlConv.h>


#define COM_RESULT_CHECK( ret )  \
    if ( ret != S_OK ) {    \
    std::stringstream ss;   \
    ss << "failed " #ret " " << std::hex << ret << std::endl;   \
    throw std::runtime_error( ss.str().c_str() );           \
    }

#define TO_STRING( ret )  \
    _com_error err(ret);   \
    LPCTSTR errMsg = err.ErrorMessage();  \
    std::string s = CT2A( errMsg );    \
    return s;   \

#endif // COMUTILITIES

Basically my goal is simple. The first function checks the return code of a com function. If it's not S_OK, then throws an error. The second one tries to convert the error code into a human-readable string and return it. Here are the error I got(the ide I'm using is qt creator but that doesn't matter): enter image description here

It says _com_error is used illegally, and other errors I believe were caused by the bad syntax in the #define block. Can someone point out what's wrong with my syntax?

1

There are 1 best solutions below

6
On

A define macro tells the preprocessor to replace what is defined with it's definition. So if you go

#define SAMPLE_TEXT 5

the preprocessor will replace all SAMPLE_TEXTs with 5. Macro functions are a little bit more complicated. So if you go

#define MACROFUN(a, b) a + b

the preprocessor will replace all MACROFUN(a, b) with a+b, and not with (a+b) or with the result of expression. So, going 2 * MACROFUN(3,3) will result in 9 (2 * 3 + 3 = 9, not 2 * 6 = 12). Preprocessor is just doing it's job pasting contents of macrofunction with replacing a, b with arguments without evaluating any values.

Returning to original question, to define a macrofunction you need here, you should probably go

#define TO_STRING( ret )  (std::string(CT2A(_com_error(ret).ErrorMessage())))

Consider avoiding using macros here and making those macrofunctions just regular functions. Let the compiler decide weather to inline them or not.