【问题标题】:A callback function with C linkage required from C++C++ 所需的具有 C 链接的回调函数
【发布时间】:2011-09-30 06:36:22
【问题描述】:

考虑以下 C++ 单例实现,将 pthread_once 用于 线程安全初始化:

class MySingleton
{
public:
     static MySingleton* Instance();

protected:
     MySingleton() {};
     static void InitOnce();

private:
    static MySingleton* instance;
};


MySingleton* MySingleton::instance = NULL;

pthread_once_t singleton_once_control = PTHREAD_ONCE_INIT;

MySingleton* MySingleton::Instance()
{
     pthread_once(&singleton_once_control, &InitOnce);
     return instance;
}

void MySingleton::InitOnce()
{
     instance = new MySingleton;
}

问题是 pthread_once 需要回调函数具有 C 链接。 (好的,这只是一个编译器警告,在我正在测试的环境中 该代码有效,因为 C 和 C++ 函数调用约定是二进制兼容的)

但是对于真正的跨平台解决方案有什么好的模式吗?您可以创建一个 C 链接包装函数,但它不能是类的一部分,因此调用私有 init 函数 InitOnce。

任何避免公开 InitOnce 的解决方案?

附:是的,单身人士很糟糕。让我们不要这样说......

【问题讨论】:

    标签: c++ c thread-safety singleton pthreads


    【解决方案1】:

    InitOnce 改为友元函数,并为其提供extern "C" 链接。

    【讨论】:

    • C-linkage 函数不能成为朋友...但当然这可以通过添加另一个包装器来解决。 extern "C" phtreadOnceCallback() { InitOnce(); }
    • @enomem:是这样吗?您能否指出标准中处理该问题的部分? C++ 从未停止让我感到惊讶。
    • @enomem:根据我对标准的阅读,我猜如果你转发声明朋友函数,你可以给它 C 链接。
    【解决方案2】:

    我不明白为什么这会是个问题。对于static 成员函数,这只是关于名称修改的问题,仅此而已。由于您的所有代码都是 C++,因此它将始终保持一致。这里唯一的语法是,在 C 中,没有参数的函数使用(void) 参数列表声明。我认为这通常不推荐用于 C++(因为没有必要),但如果这会使您收到的警告静音,您可以尝试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多