繁体   English   中英

extern“C”:什么做什么不需要它?

[英]extern “C”: What does and what doesn't need it?

关于函数的extern "C"已经存在问题,但是这个问题试图将它扩展到其他事物,例如变量等等。

如果我有一个foo.hpp头文件来使用C ++中的foo.c文件,我制作了这个模板,我填写了这个问题的简单示例:

/******************************************************************************
 ******* include guard { ******************************************************
 ******************************************************************************/
#ifndef FOO_HPP
#define FOO_HPP


/******************************************************************************
 ******* headers **************************************************************
 ******************************************************************************/
#include <cstdbool>
#include <cstddef>
#include <cstdint>


/******************************************************************************
 ******* typedefs *************************************************************
 ******************************************************************************/
/* `#if !defined(UINT128_MAX)` is to test if uint128_t already exists */
#if !defined(UINT128_MAX)
    typedef __uint128_t uint128_t;
    typedef __int128_t  int128_t;
#endif


/******************************************************************************
 ******* macros ***************************************************************
 ******************************************************************************/
#if !defined(UINT128_MAX)
    #define UINT128_MAX (~((uint128_t)0))
#endif
#if !defined(INT128_MAX)
    #define INT128_MAX  ((int128_t)(UINT128_MAX >> 1))
#endif
#if !defined(INT128_MIN)
    #define INT128_MIN  ((int128_t)(-INT128_MAX - 1))
#endif


/******************************************************************************
 ******* enums ****************************************************************
 ******************************************************************************/
enum    Some_Enum {
    SOME_CONSTANT_A,
    SOME_CONSTANT_B,

    SOME_CONSTANT_C
};


/******************************************************************************
 ******* structs / unions *****************************************************
 ******************************************************************************/
union   Some_Union {
    int128_t    a;
    int64_t     b[SOME_CONSTANT_C];
};

struct  Some_Struct {
    union Some_Union    a;
    bool                b;
};


/******************************************************************************
 ******* static const variables ***********************************************
 ******************************************************************************/
static const    struct Some_Struct  x = {
    .a  = {
        .b  = {
            [SOME_CONSTANT_A]   = 0,
            [SOME_CONSTANT_B]   = 1
        }
    },
    .b  = true
};


/******************************************************************************
 ******* C wrapper { **********************************************************
 ******************************************************************************/
extern  "C" {


/******************************************************************************
 ******* extern variables *****************************************************
 ******************************************************************************/
extern  union Some_Union    y;


/******************************************************************************
 ******* extern functions *****************************************************
 ******************************************************************************/
int foo(size_t n, int128_t arr[restrict]);


/******************************************************************************
 ******* } C wrapper **********************************************************
 ******************************************************************************/
}   /* extern "C" */


/******************************************************************************
 ******* static inline functions (prototypes) *********************************
 ******************************************************************************/
static inline   int compare_ldbl(const void *a_p, const void *b_p);


/******************************************************************************
 ******* static inline functions (definitions) ********************************
 ******************************************************************************/
static inline   int compare_ldbl(const void *a_p, const void *b_p)
{
    long double a = *(long double *)a_p;
    long double b = *(long double *)b_p;

    if (a < b)
        return  -1;
    else if (a > b)
        return  1;
    else
        return  0;
}


/******************************************************************************
 ******* } include guard ******************************************************
 ******************************************************************************/
#endif      /* foo.hpp */


/******************************************************************************
 ******* end of file **********************************************************
 ******************************************************************************/

所有类型,宏, enumstructunionextern变量和函数应与C兼容(尽可能多)。 只有static事物可以表现不同,因为我可以在标题中为C ++调整它们。

这是放置C包装器的正确位置吗?

虽然它也做其他事情,但关于extern "C"要点是禁止名称修改

名称修改主要需要两件事:

  1. 重载功能
  2. 允许在不同范围内使用相同名称的符号

由于所有全局(非命名空间)结构,枚举,类型和变量都不能重载,因此不需要名称修改,因此不需要extern "C" 它实际上只需要全局(非命名空间)功能。

extern "C"声明函数类型,函数或变量以具有C语言链接[dcl.link] / 1 如果要在C ++代码中定义可用于C代码的函数或变量,或者如果要使C ++代码使用C代码中定义的函数或变量,则需要extern "C" 而已。 这基本上是所有C ++语言都要说的事情。

与流行的看法相反, extern "C" 目的不是禁止名称修改。 名称修改不是C ++语言中存在的概念,因此,不可能有一种方法可以在C ++语言中显式控制它。 名称修改是许多(基本上所有)C ++实现在将C ++代码映射到给定目标平台时使用的机制。 这是一个实现细节。 extern "C"的目的是指示编译器做任何需要做的事情,以使给定的实体与目标平台上的C代码链接。 对于许多ABI,这意味着没有名称错误。 但是对于一些ABI,例如Windows ABI ,甚至C函数都受名称修改(在这种特殊情况下由于存在不同的调用约定)。 如果要将C ++代码与C代码链接,请使用extern "C" 这就是它的目的,这就是它的好处。 如果要控制导出或导入符号的名称,请根据给定目标平台的工具链文档使用任何方法,这通常是模块定义文件 ,链接器标志,...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM