c++ - C++ 函数的自动 C 包装器

标签 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"

实现此目标最惯用的方法是什么?

最佳答案

如果我们使用前两个代码块中的 EVAL、helper、Conditional 和 map 宏 here .

为了满足我们的需要, map 需要变得更加通用。

#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)

我们还需要 WithTypesWithoutTypes来自 here .

我们可以定义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宏。

关于c++ - C++ 函数的自动 C 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44012984/

相关文章:

C++ 位运算 : How to decode/decompress char to int, 并显示正确的字符串?

c++ - 了解 fwrite() 的缓冲行为

c++ - 如何获取 'catch(...)'中的异常信息

c++ - 使用右值的比较函数

c++ - C/C++,你能#include一个文件到一个字符串文字中吗?

c - pragma代码段和数据段有什么用?

c++ - 可变函数和折叠表达式 : Fatal Error while trying to compile in Visual Studio 2017

c - C 编译器将 "-DFOO"处理为与 "-DFOO=1"相同的事实上的标准吗?

c++ - 可变参数模板的可扩展性

c++11 - 可变模板函数的显式实例化