如何使用C宏(#define)来改变调用而不是原型

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

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

这适用于更新的代码,对于较新的C ++代码,我们只需实现全局的newdelete运算符,因此C ++解决方案更“干净”。

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

  class ABC { public: ... void free (char *p); }; 

如果类的自由方法具有相同数量的参数,则即使在类定义中,即使在调用没有类ABC的方法时,C / C ++预处理器也只是替换ourFree所有出现的free 。 所以上面的类定义和以下调用:

 ABC abc; abc.free(p); 

被替换为,

 class ABC { public: ... void OurFree (char *p); }; ABC abc; abc.OurFree(p); 

哪个可以编译,但当然没有链接。

如果ABC::free具有与标准free不同的参数数量,则编译器仍会发出警告。 我们想避免它们。

一些替代解决方案是:

  • 在第三方包含文件的开头取消定义我们的定义并在以后重新定义它
  • 确保第三方包含文件始终包含在我们自己的定义之前

但即使这样,如果我们的代码需要调用第三方类的malloc或free方法,预处理器仍然会改变调用,除非我们编写所有这样的调用:

 (abc::free)(p) 

有没有办法告诉C / C ++预处理器定义它?

  • 只能替换纯C调用
  • 原型不得更换
  • 类中的方法绝不能被替换

预处理器对范围和语义一无所知。 如此简短的回答 – 不,你不能这样做。

但是,您可以在库模块中使用#undef free 。 另一方面 – 如果从代码中调用方法abc.free() ,这将abc.free()

如何只为C而不是C ++定义那些替换:

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

为什么不直接定义自己的malloc和free函数而不是使用宏。

所以,改变:

 void *OutMalloc (size_t s) 

至:

 void *malloc (size_t s) 

以同样的方式,你可以直接操作new和删除。

我想,虽然我可能错了,但在查看库之前,链接器会在目标文件中查找符号。