【问题标题】:How can I call function with current function name in C, C++?如何在 C、C++ 中调用具有当前函数名的函数?
【发布时间】:2021-09-19 15:00:15
【问题描述】:

在开始之前,对不起我的英语不好。 环境: c、c++、VS2019、C99之后

问题: 我必须调用以被调用者名称前缀命名的函数。 我有很多被调用者和变量前缀,所以我想在预处理时处理它以方便编码。

我试过了:

`void prefix_function_name();
 void function_name(){
     (prefix_##__func__)();
 }
`

我知道这是不可能的,因为 func 是 const char[]。

所以我需要 : 使用标记而不是字符串获取函数名称。 要么 : 将字符串转换为令牌。 例如)

void foo(); const char[] a = "foo"; 
a();

有人有解决办法吗?


这是我的实际问题。

我有很多用 C 代码编写的函数。 我将使用 gtest(C++) 编写测试代码。 而且我需要对函数使用模拟(或存根)。 但是,没有办法调用模拟函数而不是原始函数。 所以我需要像这样制作钩子

`extern "C" void mock_foo();
 void foo(){
     return mock_foo(); // hook
     ... // actual code
 }
`

为了避免打字错误和人为错误,我想制作一个宏来为函数制作钩子。 现在我正在使用这样的宏。 (不详)

`#define MACRO(func_name) return mock_##func_name();
 void foo(){
     MACRO(foo) // hook
     ... // actual code
 }
`

而且我想摆脱键入函数名称。

这是我的实际问题。有什么办法吗?

【问题讨论】:

  • 这是什么语言?请选择一个。这看起来像xy problem。你为什么需要这个? (prefix_##__func__)();(假设它会起作用)如何比 prefix_function_name() 更好?
  • 我的意思是在 function_name 内部,当前函数的名称始终是 function_name 没有宏或运行时效果可以改变它
  • 为什么不直接硬编码呢?解释你的完整场景
  • 我想这是一个人必须以艰苦的方式学习的课程之一:宏不方便编码,相反。我花了一段时间才被说​​服,因为起初它们看起来很酷
  • 我支持上述 cmets:您可能试图以错误的方式解决您的问题。请描述实际问题,只有那么才能选择合适的解决方法。

标签: c++ c macros


【解决方案1】:

您无法按照您描述的方式进行操作,因为无法将字符串(变量或文字)转换为标记。您可以尝试定义调用函数的宏,例如

#define DEFINE_FUNCTION(prefix, name)  void name () { prefix ##_ ##name ();}

并使用它

void foo_func() {std::cout << "foo_func()\n";}     // assume <iostream> has been included

DEFINE_FUNCTION(foo, func)           // note no ; here

int main()
{
     func();       
}

这将起作用,因为DEFINE_FUNCTION(foo, func) 已定义func(),因此它调用foo_func()。

一般情况下,我强烈建议不要这样做。现在使用宏似乎比手动定义函数更方便。将来当您或其他人维护/扩展代码时,它似乎不会那么方便 - 特别是如果某些函数需要做的事情与宏设置略有不同。在这种情况下,您的代码很快就会变得一团糟。

【讨论】:

  • 是的。也许我应该使用更多的人力。我可以使用#define MACRO(prefix, funcname) 而不是#define MACRO(prefix)。我只是想用“__func__”代替人力。
【解决方案2】:

也许你想要这个:

void prefix_function_name();
#define INVOKER_FUNCTION(name) \
void name () {\
   prefix_##name();\
}

INVOKER_FUNCTION(function_name);

【讨论】:

  • OP想要使用C字符串作为函数名,所以这个答案可能不是这样。
  • @M.Zhang - 这不是 OP 要求的。问题是如何让func() 呼叫prefix_func()。字符串文字的描述是因为 OP 的第一个想法是使用 __func__ 预定义的宏(它给出一个以 nul 终止的字符串)来恢复函数的名称作为令牌 - 甚至 OP 也承认这不是可能。
  • 彼得是对的。我已经有了函数,想用函数名调用函数中的其他函数。
【解决方案3】:

恐怕您选择了稍微不合适的语言(我的意思是 C++)。 但, 您可以使用 dll-s 来执行此操作(在 C++ 中):

  • 将您的函数打包到外部库(.dll、.so)中。
  • 然后您可以按名称加载库和导出函数并调用它。请参阅 boost::dll:import_alias(用于跨平台代码)、LoadLibrary 和 GetProcAddress(用于 Windows)。

【讨论】:

  • 感谢您的回答,但它会太负荷。为了方便起见,我只是想制作宏。重复,谢谢你的回答。我稍后会找到这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多