У меня есть своего рода сложная проблема, которую я пытаюсь решить. Прежде всего, обзор:
У меня есть внешний API, не находящийся под моим контролем, который используется огромным количеством устаревшего кода.
- В унаследованном коде есть несколько классов ошибок, которые потенциально могут быть обнаружены во время выполнения, если бы только внешний API был написан для отслеживания собственного использования, но это не так.
- Мне нужно найти решение, которое позволило бы мне перенаправлять вызовы внешнего API в структуру отслеживания, которая будет отслеживать использование API и регистрировать ошибки.
- В идеале я хотел бы, чтобы журнал отражал файл и номер строки вызова API, вызвавшего ошибку, если это возможно.
Вот пример класса ошибок, который я хотел бы отслеживать. Используемый нами API имеет две функции. Я назову их GetAmount и SetAmount. Они выглядят примерно так:
// Get an indexed amount
long GetAmount(short Idx);
// Set an indexed amount
void SetAmount(short Idx, long amount);
Это обычные функции C. Одна ошибка, которую я пытаюсь обнаружить во время выполнения, заключается в том, что GetAmount вызывается с Idx, который еще не был установлен с помощью SetAmount.
Теперь все вызовы API содержатся в пространстве имен (назовем его api_ns), однако раньше так было не всегда. Итак, конечно, устаревший код просто выдал «используя пространство имен api_ns;» в своем файле stdafx.h и назвал его хорошим.
Моей первой попыткой было использовать препроцессор для перенаправления вызовов API в мою собственную систему отслеживания. Это выглядело примерно так:
// in FormTrackingFramework.h
class FormTrackingFramework
{
private:
static FormTrackingFramework* current;
public:
static FormTrackingFramework* GetCurrent();
long GetAmount(short Idx, const std::string& file, size_t line)
{
// track usage, log errors as needed
api_ns::GetAmount(Idx);
}
};
#define GetAmount(Idx) (FormTrackingFramework::GetCurrent()->GetAmount(Idx, __FILE__, __LINE__))
Затем в stdafx.h:
// in stdafx.h
#include "theAPI.h"
#include "FormTrackingFramework.h"
#include "LegacyPCHIncludes.h"
Это прекрасно работает для GetAmount и SetAmount, но есть проблема. API также имеет SetString(short Idx, const char* str). В какой-то момент наш унаследованный код добавил перегрузку: SetString(short Idx, const std::string& str) для удобства. Проблема в том, что препроцессор не знает и не заботится о том, вызываете ли вы SetString или определяете перегрузку SetString. Он просто видит «SetString» и заменяет его определением макроса. Что, конечно, не компилируется при определении новой перегрузки SetString.
Я потенциально мог бы изменить порядок #includes в stdafx.h, чтобы включить FormTrackingFramework.h после LegacyPCHIncludes.h, однако это означало бы, что ни один из кодов в дереве включения LegacyPCHIncludes.h не будет отслеживаться.
Итак, я думаю, у меня есть два вопроса на данный момент: 1: как мне решить проблему перегрузки API? 2: Есть ли какой-то другой способ делать то, что я хочу делать, который работает лучше?
Примечание. Я использую Visual Studio 2008 с пакетом обновления 1 (SP1).