代码之家  ›  专栏  ›  技术社区  ›  sybreon

混合低级C/C++代码

c c++
  •  2
  • sybreon  · 技术社区  · 17 年前

    我计划编写一个代码库来访问一些底层硬件(即翻转寄存器位等)。

    以前,我把所有的东西都写成C函数,并用外部的“C”来让库同时编译C和C++代码。因此,C和C++用户只需要包括头文件,并调用函数。

    现在,我想把事情组织成课堂。例如,我可以将初始化、配置、发送和接收UART的所有函数放在一个类中。这在C++中很好,但是C怎么样?我不能外接整个班级的“C”。

    我想到的一件事是:用外部“C”转义的标准C函数编写所有内容。然后,为C++提供一个包装类,它有一组内联方法调用这些“C”函数。

    int foo_bar (int *address, int data) {...} // extern C stuff
    int foo::bar (int *address, int data) { return foo_bar(address, data); } // inline method
    

    6 回复  |  直到 17 年前
        1
  •  5
  •   Mark Ransom    17 年前

    你提出的有一些先例——微软的MFC类只是C兼容的Windows API周围的C++包装。

    在你开始之前,你应该有一些目标,不仅仅是为自己创造繁忙的工作。C++应该比C更容易使用,否则你就不会得到任何东西。

        2
  •  3
  •   Daniel Earwicker    17 年前

    这样做的一个重要原因是,如果您的C接口使用典型的“句柄”习惯用法来表示资源。

    OpaqueThingHandle t = CreateOpaqueThing();
    
    DoStuffWithOpaqueThing(t);
    
    DestroyOpaqueThing(t);
    

    在C语言中,为了实现信息隐藏 OpaqueThingHandle void *

    C++包装器可以通过将RAI-映射构造和破坏应用于AgRE或释放句柄类型所标识的资源的函数,来添加一些真正有用的东西:

    class OpaqueThing : boost::noncopyable
    {
        OpaqueThingHandle handle;
    
    public:
        OpaqueThing()
            : handle(CreateOpaqueThing()) {}
    
        ~OpaqueThing()
            { DestroyOpaqueThing(handle); }
    
        void DoStuff()
            { DoStuffWithOpaqueThing(handle); }
    };
    
        3
  •  2
  •   anon anon    17 年前

    另一方面,类方法可以使C函数更易于使用,方法是为类客户机管理缓冲区等。类仍然使用C API来完成实际工作。

        4
  •  2
  •   peterchen    17 年前

    你可以双向地进行,或者围绕C函数的一个瘦C++包装,或者C++实例周围的C函数。

    对于后者,一个典型的模式是:

    void * c_open_thing(id) { return new CThing(id); }
    void c_close_thing(void * handle) { delete (CThing) handle; }
    int c_transmit(void * handle, transmitbuf) 
      { return ((CThing *)handle)->Transmit(transmitbuf); }
    

    这样一个简单的包装器是没有意义的,但不知道用哪种方式来做。C++包装器可以通过以下方式增加值:

    • 执行施工/销毁要求
      在这里,使用协构造函数/析构函数通常是不够的,除非您可以提供 reference counted handle .

    • 错误处理

    • 线程安全

        5
  •  1
  •   Diomidis Spinellis    17 年前

    我理解你想从C++的抽象能力中获益,但是仍然有代码可以用C编写代码访问。实现这一点的一种方法是在C++中编写代码的大部分,然后创建一组瘦外部“C”包装器函数,这些函数将把你的代码与C世界连接起来。

    你所建议的方法同样有效,但是,正如另一位受访者所指出的,它不会为你购买任何额外的能量。

        6
  •  1
  •   David Thornley    17 年前

    坦率地说,我不知道本质上重复C和C++功能的东西会买给你。

    我建议尽可能地保持C函数的基础性,定义一个API,其中所有的原语都是公开的,没有任何花哨的东西。然后在更高的级别定义C++类,因此UART将有构造函数、析构函数、有意义的方法等等。它将拥有所有必要的数据存储。C++类不会公开所有可能的图元;为了做一些不同的事情,您需要编写一个新的成员函数或类,或者调用C API。

    这就是OCI(Oracle C++调用接口)和MFC等系统的方法,并且它工作得很好。