使用预处理器和函数指针原型创建函数

时间:2014-04-15 17:29:37

标签: c++ c googlemock

我想一劳永逸地为这个mocks for C code创建一个漂亮而有光泽的版本。

我想创建一个如下所示的锅炉板宏:

#define MOCK_FREE_FUNCTION(NAME, SIGN, MOCK) \
  /* whatever goes here */

在代码(或标题)中,它应该像这样使用:MOCK_FREE_FUNCTION2(myFunc, void(char *, const char *), myFuncMock);并扩展为某种东西

struct Whatever_myFunc {
  MOCK_CONST_METHOD2(myFunc, void (char *x, char *y));
};

Whatever_myFunc myFuncMock;

extern "C" {
   void myFunc(char *x, char *y) {
      myFuncMock.(x,y);
   }
}

/* maybe some convenience EXPECT_CALL thing */

我很清楚并非一切皆有可能,但我希望尽可能接近这一点。只要链接器没有抱怨并找到它的符号,我也不会抱怨。如果它有两个不同的宏,我不介意:一个用于定义静态成员,另一个用于定义原型。

从评论中添加

生成大部分内容很简单 我不能完成的问题是 gmock如何设法从

获得

MOCK_METHOD2(foo, void(char *, char*)

类似于void foo(char *, char*)

这是我能提出的最接近的事情:

#include <stdio.h>

#define MOCK_FREE_FUNCTION2(NAME, MOCK, RET, ARGS) \
  typedef RET (*NAME ## Type) ARGS; \
  NAME ## Type NAME = barfoo_f;

/* ok it's callable, but how do I get my own code inside here? */
void barfoo_f(int i, int j) {
  printf ("hello world %d %d\n", i, j);
}

// How does google mock get rid of , in the prototype
MOCK_FREE_FUNCTION2(FooBar, XXX, void, (int,int));

int main(int argc, char **argv) {
  FooBar(1,2);
}

1 个答案:

答案 0 :(得分:1)

解决您的近似问题(如何从MACRO(foo, void(char*, char*))void foo(char*, char*))的可能方法可能与功能特征结合使用:

template <typename F>
struct func_traits;

template <typename R, typename... Args>
struct func_traits<R(Args...)>
{
    using return_type = R;

    template <size_t I>
    using arg_type = typename std::tuple_element<I, std::tuple<Args...>>::type;
};

#define MACRO_2(NAME, TYPE)                                                  \
    func_traits<TYPE>::return_type NAME(func_traits<TYPE>::arg_type<0> arg0, \
                                        func_traits<TYPE>::arg_type<1> arg1)

(我只是使用std::tuple作为在此处实施类型列表的快捷方式。)