从C库调用C++函数指针

ana*_*lyg 5 c++

我有一个只有静态成员的类.

我想在退出时使用"atexit"库函数注册其成员函数之一(下面的代码中的VerifyClean).

C++常见问题解答说,我必须指定为extern"C"为我要注册这样,就像在下面的例子中的功能.

class Example
{
public:
    static void Initialize();
    static void DoDirtyStuff {++dirtLevel;}
    static void CleanUpStuff {--dirtLevel;}
private:
    static void VerifyClean();
    // DOESN'T COMPILE: extern "C" static void VerifyClean();
    static int dirtLevel;
}

int Example::dirtLevel;

extern "C" void Example::VerifyClean() // DO I NEED extern "C" HERE?
{
    assert(dirtLevel == 0);
}

void Example::Initialize()
{
    dirtLevel = 0;
    atexit(&VerifyClean);
}
Run Code Online (Sandbox Code Playgroud)

我真的必须使用extern"C"吗?

如果我将"atexit"替换为非库函数(在纯C中实现),答案是否会改变?

如果函数VerifyClean是公共的,我决定直接从C++代码调用它,我会得到链接错误或运行时崩溃吗?我问这个是因为声明根本没有提到extern"C",所以常规的C++代码可能会错误地处理函数调用.这在我的MS Visual Studio 2005系统上运行正常.

Joh*_*kin 7

这是可能的一个编译器使用为C和C++代码不同的调用约定; 然而,在实践中,这几乎从未发生过.

如果你只是想让它工作而不关心支持晦涩的编译器,请不要理会extern "C".在任何广泛使用的编译器中都没有必要.

如果你想要绝对迂腐,或者需要支持一个迂腐的编译器,写一个包装器:

extern "C" static void ExampleVerifyClean()
{
  Example::VerifyClean();
}

void Example::Initialize()
{
    dirtLevel = 0;
    atexit(&ExampleVerifyClean);
}
Run Code Online (Sandbox Code Playgroud)