具有C语言绑定的静态成员函数?
static member function with C language binding?
以下 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 函数相同的调用约定(如果不是,如何这并不意味着)?
静态成员函数与 C 函数具有相同的调用约定。但是,名称修改适用。因此,即使您将静态成员声明为 extern "C"
,当您尝试针对调用该函数的 C 代码 link 时,link 用户也可能找不到它。
您可以 轻松地做的是声明一个wrapper/stub,它从普通函数调用静态成员。此外,您可以将静态成员函数的地址分配给普通函数指针。
C++11 7.5/4 "Linkage specifications"
A C language linkage is ignored in determining the language linkage of
the names of class members and the function type of class member
functions.
因此您的示例在没有格式错误或错误的意义上是有效的,但是 extern "C"
应该对 S::foo()
或 T::foo()
.
没有影响
不,它被忽略了,问题是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模块中定义。
以下 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 函数相同的调用约定(如果不是,如何这并不意味着)?
静态成员函数与 C 函数具有相同的调用约定。但是,名称修改适用。因此,即使您将静态成员声明为 extern "C"
,当您尝试针对调用该函数的 C 代码 link 时,link 用户也可能找不到它。
您可以 轻松地做的是声明一个wrapper/stub,它从普通函数调用静态成员。此外,您可以将静态成员函数的地址分配给普通函数指针。
C++11 7.5/4 "Linkage specifications"
A C language linkage is ignored in determining the language linkage of the names of class members and the function type of class member functions.
因此您的示例在没有格式错误或错误的意义上是有效的,但是 extern "C"
应该对 S::foo()
或 T::foo()
.
不,它被忽略了,问题是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模块中定义。