如何使用 C 宏 (#define) 更改调用但不更改原型

发布于 2024-08-22 10:21:21 字数 1253 浏览 3 评论 0原文

我们应用程序中的旧代码包含对 mallocreallocfree 的调用。使用更新后的代码,将调用我们自己的实现,而不是标准运行时的实现。示例如下所示,

#define malloc(s) OurMalloc(s)
#define free(p)   OurFree(p)

这对于更新的代码来说效果很好,对于较新的 C++ 代码,我们只需实现全局 newdelete 运算符,因此 C++ 解决方案更加“干净”。

问题是我们现在必须包含一个第三方库,其中的类包含名称类似于 mallocfree 的方法,例如,

   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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里°也失望 2024-08-29 10:21:21

只定义 C 而不是 C++ 的替换怎么样:

#ifndef __cplusplus
#  define malloc(s) OurMalloc(s)
#  define free(p)   OurFree(p)
#endif

How about only defining those replacements for C and not C++:

#ifndef __cplusplus
#  define malloc(s) OurMalloc(s)
#  define free(p)   OurFree(p)
#endif
睫毛上残留的泪 2024-08-29 10:21:21

为什么不定义自己的 malloc 和 free 函数而不是使用宏呢?

因此,将: 更改

void *OutMalloc (size_t s)

void *malloc (size_t s)

:以与您可以直接操作new 和delete 相同的方式。

我认为,尽管我可能是错的,链接器会在查找库之前在目标文件中查找符号。

Why don't you just define your own malloc and free functions instead of using macros.

So, change:

void *OutMalloc (size_t s)

to:

void *malloc (size_t s)

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.

二智少女 2024-08-29 10:21:21

预处理器对范围和语义一无所知。答案很简短——不,你不能那样做。

但是,您可以在库模块中使用#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 methods abc.free() from your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文