具有C语言绑定的静态成员函数?

时间:2015-12-02 07:38:10

标签: c++ c member-functions

以下C ++代码使用Visual C ++和g ++进行编译:

struct S
{
    static void foo();
};

extern "C"
void S::foo() {}

struct T
{
    static void foo();
};

extern "C"
void T::foo() {}

auto main() -> int
{
    S().foo();
    T().foo();
}
  • 有效吗?

  • 如果它是有效的,因为实现可能在一个单独的翻译单元中,这是否意味着静态成员函数总是具有与C函数相同的调用约定(如果不是,它如何不暗示)?

3 个答案:

答案 0 :(得分:8)

C ++ 11 7.5 / 4“链接规范”

  

在确定语言链接时忽略C语言链接   类成员的名称和类成员的函数类型   功能

因此,您的示例在没有格式错误或错误的意义上是有效的,但extern "C"应该对S::foo()T::foo()没有影响。

答案 1 :(得分:4)

静态成员函数与C函数具有相同的调用约定。但是,名称修改适用。因此,即使您将静态成员声明为extern "C",当您尝试将其与调用该函数的C代码链接时,链接器也可能找不到它。

可以轻松做的是声明一个从普通函数调用静态成员的包装器/存根。此外,您可以将静态成员函数的地址分配给普通函数指针。

答案 2 :(得分:0)

不,它被忽略,问题是 name mangling (链接阶段的函数命名)。所以诀窍是定义一个C函数并使用你的C ++静态方法作为存根来调用它,如下所示:

struct S
{
    static void foo();
};

extern "C" void S_foo_impl();
void S::foo() { S_foo_impl(); }

auto main() -> int
{
    S::foo();
}

当然,S_foo_impl应该在外部C模块中定义。