How do I include a trace statement in a C/C++ macro?
Strictly speaking, you cannot have a trace statement within a macro, because the WPP preprocessor runs before the C preprocessor. One solution is to run the C preprocessor twice, but there is an even simpler solution: define optional PRE and POST steps to the trace macros.
For example, you might want an "exit on failed" macro, such as
If (FAILED(HR)) {
DoTraceMessage(ERROR,"We failed!");
Goto done ;
}
In this case, using PRE and POST forms of the macro makes this possible.
Define the function
In the source file, define the function, for example:
FUNC:_EXIT_IF_EXP_FAILED{LEVEL=WSM_ERROR}(_EXIT_IF_EXP_FAILED_EXP,MSG,...)
Define the macros
In a header file, add the following definition directives. Put them after the WPP_CONTROL_GUIDS definition and before the #include statement for the trace message header file.
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_PRE(LEVEL, HR) {HRESULT hr=S_OK ; if(FAILED(hr = HR)) {
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_POST(LEVEL, HR) ; goto done; } }
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_ENABLED(LEVEL, HR) WPP_LEVEL_ENABLED(LEVEL)
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_LOGGER(LEVEL, HR) WPP_LEVEL_LOGGER(WSM_ERROR)
Add formatting
You can make the trace messages easier to read by including formatting data in the header file. This step is optional.
// MACRO: _EXIT_IF_EXP_FAILED
//
// begin_wpp config
// USEPREFIX (_EXIT_IF_EXP_FAILED,"%!STDPREFIX!");
// FUNC _EXIT_IF_EXP_FAILED{LEVEL=WSM_ERROR}(_EXIT_IF_EXP_FAILED_EXP,MSG,...);
// USESUFFIX (_EXIT_IF_EXP_FAILED," hr= %!HRESULT!", hr);
// end_wpp
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_PRE(LEVEL, HR) {HRESULT hr=S_OK ; if(FAILED(hr = HR)) {
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_POST(LEVEL, HR) ; goto done; } }
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_ENABLED(TRACELEVEL, HR) WPP_LEVEL_ENABLED(TRACELEVEL)
#define WPP_LEVEL__EXIT_IF_EXP_FAILED_EXP_LOGGER(LEVEL, HR) WPP_LEVEL_LOGGER(WSM_ERROR)
In this example, the begin_wpp config and end_wpp statements identify the configuration data in the header file for WPP.
Also, to notify WPP that there is configuration data in the header file, add the -scan parameter to the RUN_WPP macro that invokes the WPP preprocessor. For example:
RUN_WPP -scan:trace.h
For a complete list of the optional parameters for RUN_WPP, see WPP Preprocessor.
Use the macros
In the source code, use the macros, such as in the following call:
_EXIT_IF_EXP_FAILED(hr,"it failed");