且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

包裹在C C ++库? (不要"外部C")

更新时间:2022-12-08 18:47:49

您可以用C的面向对象的code,因此,如果它是一个面向对象的C ++库,它可能把它包在一个C接口。但是,这样做可能是非常繁琐的,特别是如果你需要支持继承,虚函数和这样的东西。

You can write object-oriented code in C, so if it's an object-oriented C++ library, it's possible to wrap it in a C interface. However, doing so can be very tedious, especially if you need to support inheritance, virtual functions and such stuff.

如果C ++库使用泛型编程(模板),它可能得到真正毛毛(你需要提供模板的全部所需的实例),并快速接近的地方,它只是不值得做的地步。

If the C++ library employs Generic Programming (templates), it might get really hairy (you'd need to provide all needed instances of a template) and quickly approaches the point where it's just not worth doing it.

假设它是面向对象的,这里有一个如何你可以在C做OO一个基本的素描:

Assuming it's OO, here's a basic sketch of how you can do OO in C:

C ++类:

class cpp {
  public:
    cpp(int i);
    void f();
};

C接口:

#ifdef __cplusplus
extern "C" {
#endif
  typedef void* c_handle;

  c_handle c_create(int i)
  {
    return new cpp(i);
  }

  void c_f(c_handle hdl)
  {
    static_cast<cpp*>(hdl)->f();
  }

  void c_destroy(c_handle hdl)
  {
    delete static_cast<cpp*>(hdl);
  }
#ifdef __cplusplus
}
#endif

根据您的要求,您可以修改的。例如,如果这将是一个公共C接口的私人C ++ API,端出真正的指针作为手柄可能使脆弱。在这种情况下,你会把手伸到处理在本质上是整数,存储在一个句柄到指针地图指针,取代查找投。

Depending on your requirements, you could amend that. For example, if this is going to be a public C interface to a private C++ API, handing out real pointers as handles might make it vulnerable. In that case you would hand out handles that are, essentially, integers, store the pointers in a handle-to-pointer map, and replace the cast by a lookup.

已经返回字符串和其他动态调整资源的功能也可能变得非常复杂。您会需要C呼叫者提供缓冲,但它不能知道前手的尺寸。一些API(例如在Win32 API的部分),然后允许调用者调用这样的功能与长度为0的缓冲器,在这种情况下,它们返回所需要的缓冲区的长度。然而这样做,可以使呼叫通过API效率极其低下。 (如果只知道执行的算法后所需的缓冲区的长度,它需要被执行两次。)结果,
有一件事我已经在过去做的是来伸手,句柄(类似于上面code手柄),以内部存储字符串,并提供了一​​个API,要求所需的缓冲区大小,检索该字符串设置缓冲,并摧毁手柄(这将删除内部存储的字符串)。结果
这是一个真正的PITA使用,但这样是C

Having functions returning strings and other dynamically sized resources can also become quite elaborate. You would need the C caller provide the buffer, but it can't know the size before-hand. Some APIs (like parts of the WIn32 API) then allow the caller to call such a function with a buffer of the length 0, in which case they return the length of the buffer required. Doing so, however, can make calling through the API horribly inefficient. (If you only know the length of the required buffer after the algorithm executed, it needs to be executed twice.)
One thing I've done in the past is to hand out handles (similar to the handle in the above code) to internally stored strings and provide an API to ask for the required buffer size, retrieve the string providing the buffer, and destroy the handle (which deletes the internally stored string).
That's a real PITA to use, but such is C.