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

Automatic C wrappers for C++ functions

本文关键字:包装 C++ 函数 用于      更新时间:2023-10-16

假设我有一些名为 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、帮助程序、条件和映射宏。

地图需要

更加通用,以满足我们的需要。

#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

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