Поэтому я работаю над приложением для Windows и решил написать несколько вспомогательных функций для проверки HRESULT, возвращаемого любой связанной с com функцией при ее вызове. Я пытаюсь определить эти функции в блоке макроса #define, но я действительно не уверен, каков правильный синтаксис. Вот две функции в блоке #define, а вторая выдает ошибку компилятора, когда другие части моей программы вызывают ее.
#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
В основном моя цель проста. Первая функция проверяет код возврата функции com. Если это не S_OK, то выдает ошибку. Второй пытается преобразовать код ошибки в удобочитаемую строку и вернуть его. Вот ошибка, которую я получил (идея, которую я использую, является Qt Creator, но это не имеет значения):
В нем говорится, что _com_error используется незаконно, и другие ошибки, которые, я считаю, были вызваны неправильным синтаксисом в блоке #define. Может кто-нибудь указать, что не так с моим синтаксисом?
Макрос определения говорит препроцессору заменить то, что определено, его определением.
Так что если вы идете
#define SAMPLE_TEXT 5
препроцессор заменит все SAMPLE_TEXT
с 5.
Макро-функции немного сложнее. Так что если вы идете
#define MACROFUN(a, b) a + b
препроцессор заменит все MACROFUN(a, b)
с a+b
а не с (a + b) или с результатом выражения. Итак, собираемся 2 * MACROFUN(3,3)
приведет к 9 (2 * 3 + 3 = 9, а не 2 * 6 = 12). Препроцессор просто выполняет свою работу, вставляя содержимое макрофункции с заменой аргументов a, b без оценки каких-либо значений.
Возвращаясь к исходному вопросу, чтобы определить макрофункцию, которая вам нужна, вам, вероятно, следует
#define TO_STRING( ret ) (std::string(CT2A(_com_error(ret).ErrorMessage())))
Попробуйте не использовать здесь макросы и делать эти макрофункции просто обычными функциями. Пусть компилятор решит погоду встроить их или нет.
Других решений пока нет …