如何使用 C 宏 (#define) 更改调用但不更改原型
我们应用程序中的旧代码包含对 malloc
、realloc
和 free
的调用。使用更新后的代码,将调用我们自己的实现,而不是标准运行时的实现。示例如下所示,
#define malloc(s) OurMalloc(s)
#define free(p) OurFree(p)
这对于更新的代码来说效果很好,对于较新的 C++ 代码,我们只需实现全局 new
和 delete
运算符,因此 C++ 解决方案更加“干净”。
问题是我们现在必须包含一个第三方库,其中的类包含名称类似于 malloc
和 free
的方法,例如,
class ABC
{
public:
...
void free (char *p);
};
如果该类的 free 方法具有相同数量的参数,C/C++ 预处理器只需将所有出现的 free
替换为 ourFree
,即使在类定义中,甚至在调用类的 free 方法时也是如此ABC
。 因此,上面的类定义和下面的调用:
ABC abc;
abc.free(p);
被替换为,
class ABC
{
public:
...
void OurFree (char *p);
};
ABC abc;
abc.OurFree(p);
可以编译,但当然不能链接。
如果 ABC::free 的参数数量与标准 free 不同,编译器仍会发出警告。我们想避开它们。
一些替代解决方案是:
- 在第 3 方包含文件的开头取消定义我们的定义,然后重新定义它,
- 确保第 3 方包含文件始终包含在我们自己的定义之前
但是即使如此,如果我们的代码需要调用这些 malloc 或第三方类的自由方法,预处理器仍然会改变调用,除非我们像这样编写所有调用:
(abc::free)(p)
有没有办法告诉 C/C++ 预处理器定义这一点?
- 仅纯 C 调用必须被替换
- 原型不得被替换
- 类中的方法不得被替换
Older code in our application contains calls to malloc
, realloc
and free
. With our updated code, our own implementations are called instead of the standard runtime ones. Examples are shown below,
#define malloc(s) OurMalloc(s)
#define free(p) OurFree(p)
This works fine for the updated code and for the newer C++ code we simply implement global new
and delete
operators, so the C++ solution is 'cleaner'.
The problem is that we now have to include a 3rd party library, which has classes that contain methods that have names like malloc
and free
, e.g.
class ABC
{
public:
...
void free (char *p);
};
If the free method of the class has the same number of arguments, the C/C++ preprocessor simply replaces all occurrences of free
by ourFree
, even in the class definition, even when calling the method free of the class ABC
.
So the class definition above and the following call:
ABC abc;
abc.free(p);
are replaced by,
class ABC
{
public:
...
void OurFree (char *p);
};
ABC abc;
abc.OurFree(p);
Which may compile, but which doesn't link of course.
If ABC::free
has a different number of arguments than the standard free, the compiler still gives a warning. we would like to avoid them.
Some alternative solutions are:
- undefining our defines in the beginning of the 3rd party include file and redefining it later
- make sure that the 3rd party include file is always included before our own define's
But even then, if our code is required to call these malloc or free methods of the 3rd party classes, the preprocessor will still alter the calls, unless we write all calls like this:
(abc::free)(p)
Is there a way to tell a C/C++ preprocessor define that?
- only pure C-calls must be replaced
- prototypes MUST NOT be replaced
- methods in classes MUST NOT be replaced
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只定义 C 而不是 C++ 的替换怎么样:
How about only defining those replacements for C and not C++:
为什么不定义自己的 malloc 和 free 函数而不是使用宏呢?
因此,将: 更改
为
:以与您可以直接操作new 和delete 相同的方式。
我认为,尽管我可能是错的,链接器会在查找库之前在目标文件中查找符号。
Why don't you just define your own malloc and free functions instead of using macros.
So, change:
to:
in the same way that you can overright operator new and delete.
I think, although I may be wrong, the linker will look in object files for symbols before looking in libraries.
预处理器对范围和语义一无所知。答案很简短——不,你不能那样做。
但是,您可以在库模块中使用
#undef free
。另一方面 - 如果您从代码中调用方法abc.free()
,这将无济于事。Preprocessor know nothing about about scope and semantic. So short answer - no, you can't do that.
But, you can use
#undef free
in library modules. On other side - this will not help, if you call methodsabc.free()
from your code.