gpt4 book ai didi

c++ - 对于外部 API 的运行时跟踪,是否有比预处理器重定向更好的替代方法?

转载 作者:太空宇宙 更新时间:2023-11-04 12:26:17 24 4
gpt4 key购买 nike

我正试图解决一个棘手的问题。首先,概述:

我有一个不受我控制的外部 API,它被大量遗留代码使用。

  • 遗留代码中有几类错误可能会在运行时检测到,如果只编写外部 API 来跟踪其自身的使用情况,但事实并非如此。
  • 我需要找到一个解决方案,使我能够将对外部 API 的调用重定向到跟踪框架,以跟踪 API 使用情况和记录错误。
  • 理想情况下,如果可能的话,我希望日志反射(reflect)触发错误的 API 调用的文件和行号。

这是我想要跟踪的一类错误的示例。我们使用的 API 有两个功能。我将它们称为 GetAmount 和 SetAmount。它们看起来像这样:

// Get an indexed amount
long GetAmount(short Idx);

// Set an indexed amount
void SetAmount(short Idx, long amount);

这些是常规的 C 函数。我试图在运行时检测的一个错误是,当使用尚未使用 SetAmount 设置的 Idx 调用 GetAmount 时。

现在,所有 API 调用都包含在一个命名空间中(称之为 api_ns),但过去并不总是如此。所以,遗留代码当然只是抛出一个“using namespace 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 重载时当然不会编译。

我可能会对 stdafx.h 中的#includes 重新排序,以在 LegacyPCHIncludes.h 之后包含 FormTrackingFramework.h,但这意味着 LegacyPCHIncludes.h 包含树中的任何代码都不会被跟踪。

所以我想我现在有两个问题:1:如何解决API过载问题?2:有没有其他方法可以更好地完成我想做的事情?

注意:我使用的是带有 SP1 的 Visual Studio 2008。

最佳答案

好吧,对于需要重载的情况,您可以使用一个类实例来重载 opera() 的多个参数。

#define GetAmount GetAmountFunctor(FormTrackingFramework::GetCurrent(), __FILE__, __LINE__)

然后,制作一个 GetAmountFunctor:

 class GetAmountFunctor
{
public:
GetAmountFunctor(....) // capture relevant debug info for logging
{}

void operator() (short idx, std::string str)
{
// logging here
api_ns::GetAmount(idx, str);
}

void operator() (short idx)
{
/// logging here
api_ns::GetAmount(Idx);
}
};

这是非常多的伪代码,但我想你明白了。无论在遗留代码中哪里提到了特定的函数名称,它都会被仿函数对象替换,并且该函数实际上是在仿函数上调用的。请考虑您只需要为存在重载问题的函数执行此操作。要减少胶水代码量,您可以为参数 __FILE____LINE__ 创建一个结构,并将其作为一个参数传递给构造函数。

关于c++ - 对于外部 API 的运行时跟踪,是否有比预处理器重定向更好的替代方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2313735/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com