【问题标题】:Are there any pitfalls when calling functions from a C library in a C++ program?在 C++ 程序中调用 C 库中的函数时是否有任何陷阱?
【发布时间】:2010-04-13 21:38:45
【问题描述】:

我在我的 C++ 程序中使用了一个同时具有 C 接口和 C++ 接口的库。 C++ 有点不成熟,我必须坚持使用 C。我想知道,更笼统地说,在将 C 风格的二进制对象文件与 C++ 项目混合时,有什么需要特别注意的吗?

【问题讨论】:

    标签: c++ c


    【解决方案1】:

    对于要从 C++ 调用的 C 函数,它们必须声明为 extern "C"。通常在标题中使用这样的东西:

    #if defined(__cplusplus)
    extern "C" {
    #endif
    
    void f();
    void g();
    
    #if defined(__cplusplus)
    }
    #endif
    

    【讨论】:

      【解决方案2】:

      C 函数必须声明为 extern "C",如果您的 C 头文件不自动执行此操作,您可以对整个头执行此操作:

      extern "C"
      {
          #include "c-library.h"
      }
      

      否则,只要您使用 C++ 链接器,一切都会好起来的 :)。

      【讨论】:

      • 运行时链接器不是 C 或 C++ 特定的。无论如何,C 函数都需要声明为extern "C"
      【解决方案3】:

      在从 C++ 处理 C 库时非常有用的一件事是RAII。假设你的 C 库有初始化和释放函数,可以很容易地封装到资源管理类中:

      #include <boost/utility.hpp>
      
      /// Base class for top-level library objects
      class lib_base: boost::noncopyable
      {
      protected:
      
          lib_base()
          {
              if ( my_c_lib_init() == -1 )
                  throw std::runtime_error( "no C lib" );
          }
      
          ~lib_base() { my_c_lib_fini(); }
      };
      
      /// Widget from C library
      class widget: lib_base
      {
      public:
      
          widget( const std::string& name ) :
              lib_base(), pcw_()
          {
              if (( pcw_ = my_c_lib_alloc_widget( name.c_str())) == NULL )
                  throw std::runtime_error( "no more widgets" );
          }
      
          ~widget() { my_c_lib_release_widget( pcw_ ); }
      
      private:
      
          c_widget* pcw_; //< low-level widget
      };
      

      这当然使子类不可复制,但这可以通过包含和/或智能指针来解决。

      【讨论】:

        【解决方案4】:

        从 C++ 程序调用 C 函数是很常见的。只需要记住一件事 - 使用 C++ 链接器 :) 还要记住 C 函数不能使用异常,因此您必须检查它们的返回值。

        编辑:其他人指出 C 函数声明应该包含在 extern "C" {...} 中。通常这已经在库头文件中完成了。

        【讨论】:

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