在代码中定义指令来分隔代码版本
Define directive inside code to separate code versions
我正在修改别人写的代码。
现有代码包含算法,在两种情况下有效。它们之间的差别很小——只是一些数据类型,有时在处理过程中会多出几行。
原始代码将所有内容设置为
#define ABC
#ifdef ABC
typedef struct {
unsigned char a, b, c;
} MyStruct;
#else
typedef unsigned char MyStruct;
#endif
#if defined(ABC)
#define SIZE1 3
#else
#define SIZE1 2
#endif
typedef struct {
MyStructtable[SIZE1];
} MyStructA;
void MyMethod(){
statement1;
#if defined(ABC)
staement2;
#endif
}
它是……如果选择是在源代码中做出的,但我试图让用户选择使用一个版本或另一个版本,并且在分离代码时遇到了最难的困难。
我可以为每个版本创建一套完整的文件。我遇到的问题:
由于存在复杂的算法,因此将算法保存在一个地方是有意义的…如果在一个版本而不是在其他版本中进行更改,则复制代码可能导致错误。
我试图做一些类型为
的事情if(option)
{
#define ABC
}
else
{
#undef ABC
}
,但调试器跳过,即使在检查"yes"分支时也没有看到定义的ABC。
是否有一种方法来解开这个代码,或者我必须创建明确的单独的路径-复制整个代码?
我以前做过类似的事情。我有一个没有源代码的库,但我有一个头文件。有大量的代码也使用了这个库,远远超出了我自己的能力范围。
嗯,我必须编写另一个库来做与另一个库相同的事情,但使用不同的设备,驱动程序等。你懂的。所以在运行时,我想用我的库代替他们的库,但仍然能够使用旧的(必须向后兼容)。
所以我是这样做的:我想出了一些方便的宏,可以将文本转换为其他定义。有2个头文件和一个源文件。例如,假设我想在运行时用FooLibrary代替BarLibrary selectable。在一个名为FooLibrary.h:
的头文件中// don't ask me why, but two levels of indirection is necessary
// to pull off a certain concatenation
// this I got from another question on SO
#define CAT(x, y) x ## y
#define cat(x, y) CAT(x, y)
#ifdef FOO_HIJACK_NAMESPACE
// library init functions
bool ShouldHijack();
void SetHijack(bool yn);
// handy-dandy function-changing macros
#define FOO_FN_NAME(X) cat(X, FOO_HIJACK_NAMESPACE)
#define FOO_FN_NAME_NS(X) FOO_HIJACK_NAMESPACE :: FOO_FN_NAME(X)
#define FOO_DECL(X) FOO_API FOO_FN_NAME(X)
#define FOO_IMPL(X) FOO_API FOO_FN_NAME_NS(X)
#define FOO_CALL(X) (ShouldHijack() ? FOO_FN_NAME_NS(X) : X)
namespace FOO_HIJACK_NAMESPACE {
#else
#define FOO_DECL(X) X
#define FOO_IMPL(X) X
#define FOO_CALL(X) X
#endif // FOO_HIJACK_NAMESPACE
然后,在这个命名空间包装器中,像这样重新定义函数调用:假设在另一个库中有一个函数bool BarFun(fooargs...)
,您可以将其重新定义为
bool FOO_DECL(BarFun)(fooargs...);
// more FOO_DECL's...
在FooLibrary.h 。FOO_API
是通常的cdecl
类型的垃圾,对于我来说,我做的是#define FOO_API WINAPI
。在末尾添加类似的声明,不要忘记关闭命名空间:
#ifdef FOO_HIJACK_NAMESPACE
}
#endif // FOO_HIJACK_NAMESPACE
然后,在FooLibrary.cpp中,提供如下实现:
#include "FooLibrary.h"
// hijack
static bool bShouldHijack = false;
bool ShouldHijack() { return bShouldHijack; }
void SetHijack(bool yn) { bShouldHijack = yn; }
bool FOO_IMPL(BarFun)(fooargs...)
{
// your implementation here...
}
// more FOO_IMPL's...
等等。最后,再创建一个头文件,我将其命名为"FooLibraryHijacked.h":
#include "FooLibrary.h"
#define BarFun FOO_CALL(BarFun)
// more #define's...
为每个函数提供一个重新声明、一个重新实现和一个#define
。我有大约20个这样的函数,所以我使用regex为我生成它们。
最后,在目标代码文件中,将#include "FooLibraryHijacked.h"
作为最后一个#include
,或者至少在#include "BarLibrary.h"
之后使用它。然后#define
宏FOO_HIJACK_NAMESPACE
作为某个东西,说"Foo",BarFun
在预处理器得到它之后变成Foo::BarFunFoo
。
现在如何使用单独的类型定义将是有趣的。如果应用程序代码只是将变量从一个函数传递到另一个函数,也许您可以使用不透明指针。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- C++逗号分隔的输入数组代码过早退出
- 如何用逗号分隔输出?如何改进此代码以使其看起来更体面?
- 无括号循环中以逗号分隔的代码行
- 用于分隔整个部分和小数部分的代码
- 在执行其中的代码之前,是否处理了 if 中的所有逻辑 OR 分隔检查?
- 字符串流代码分隔单词 - 这个东西是如何工作的?里面的代码片段
- 在代码中定义指令来分隔代码版本
- 如何在C或c++代码中分隔数字常量(例如10,000)中的数字