用于C ++函数的自动C包装器

时间:2017-05-16 23:04:04

标签: c++ c-preprocessor variadic-templates

我们说我有一些名为variant的未指定类型,以及两个允许转换为此类型的函数,具有以下签名:

struct converter
{
  template<typename T>
  static variant to(const T&);

  template<typename T>
  static T from(const variant&);
};

现在,我要做的是为任意C ++函数创建包装器,如下例所示:

SomeObject f_unwrapped(const std::string& s, int* x)
{
    //... do something with the inputs... 
    return SomeObject();
}

extern "C" variant f(variant s, variant x)
{
   return converter::to<SomeObject>(f_unwrapped(converter::from<std::string>(s), converter::from<int*>(x)));
}

理想情况下,我希望包装器是一行声明或宏,只需要f_unwrapped函数和名称f作为输入。

我试图将函数包装到函数对象中,然后使用可变参数模板进行官僚作业。虽然这确实有效,但我不知道如何制作结果函数extern "C"

实现这一目标的最惯用方式是什么?

1 个答案:

答案 0 :(得分:0)

如果我们使用前两个代码块here中的EVAL,helper,Conditional和map宏。<​​/ p>

为了满足我们的需求,地图需要更加通用。

#define MM1() MM_CALL1
#define MM_NEXT1(Macro,a,...)      \
  IS_DONE(a)(                       \
     EAT                             \
  ,                                   \
     OBSTRUCT(COMMA)() OBSTRUCT(MM1)() \
  )                                     \
  (Macro,a,__VA_ARGS__)
#define MM_CALL1(Macro,a,...)   \
  Macro(a)                       \
  MM_NEXT1(Macro,__VA_ARGS__)
#define MacroMap1(Macro,...) MM_CALL1(Macro,__VA_ARGS__,DONE)

#define MM2() MM_CALL2
#define MM_NEXT2(Macro,a,...)      \
  IS_DONE(a)(                       \
     EAT                             \
  ,                                   \
     OBSTRUCT(COMMA)() OBSTRUCT(MM2)() \
  )                                     \
  (Macro,a,__VA_ARGS__)
#define MM_CALL2(Macro,a,b,...)   \
  Macro(a,b)                       \
  MM_NEXT2(Macro,__VA_ARGS__)
#define MacroMap2(Macro,...) MM_CALL2(Macro,__VA_ARGS__,DONE)

我们还希望来自hereWithTypesWithoutTypes

我们可以定义AMACRO来完成您想要的工作。

#define AsVariant(param) variant param
#define ConvertFrom(type,param) converter::from<type>(param)
#define HEADDER(type,func,params) type func ##_unwrapped (WithTypes params)
#define WRAPPER(type,func,params) \
   extern "C" variant func (OBSTRUCT(MacroMap1)(AsVariant,WithoutTypes params)) \
   { \
   return converter::to< type >(func ## _unwrapped( \
         MacroMap2(ConvertFrom,IDENT params) \
      )); \
   }

#define AMACRO(type,func,params) \
  EVAL(                           \
    HEADDER(type,func,params);     \
    WRAPPER(type,func,params)       \
    HEADDER(type,func,params)        \
  )

这将转变为:

AMACRO(SomeObject,f,(const std::string&, s, int*, x))
{
     // ... do something with the inputs ...
     return SomeObject();
}

进入此(格式化后):

SomeObject f_unwrapped (const std::string& s , int* x );

extern "C" variant f (variant s , variant x )
{
   return converter::to<SomeObject>(f_unwrapped(converter::from<const std::string&>(s),converter::from<int*>(x)));
}

SomeObject f_unwrapped (const std::string& s , int* x )
{
   return SomeObject();
}

注意: 如果const需要从参数中移除,则可以制作类似于ISDONE的条件,并将其添加到ConvertFrom宏。