Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should third-party types be exposed in my C++ library's API

Tags:

c++

api

I'm developing a C++ library where user's will provide complex inputs, such as matrices and quaternions. I don't want to have to reimplement these types so, internally, I'll be using the Eigen library.

I'm trying to decide on the best way to expose these types to my libraries' clients and have come up with a few options for my API. I use a quaternion type as an example, but this could apply equally to matrices and such. Also, although I'm specifically talking about exposing Eigen's types, I guess this question can apply equally well to other external libraries in use.

1) Use only basic C++ types

This option would require clients to pass data in via basic types. For example, for passing in a quaternion (4 elements), one could do:

void my_func(double my_quat[4])

2) Expose Eigen's Types

Eigen provides several templated types for arrays and quaternions. For example, if a function requires a quaternion, I could use Eigen's Quaterniond type (which is really a typedef for Quaternion<double>):

void my_func(const Eigen::Quaterniond& my_quat)

3) Create a simple wrapper for the various types for clients

I could create a very simple quaternion type (say, some sort of simple struct) that clients would have to create (perhaps via some sort of factory function) to pass to my API:

void my_func(const quaternion_t& my_quat)

My library would convert the quaternion_t type to my internal Eigen representation.

I don't like option 1 too much since I want there to be a stronger sense of typing in my APIs. Option 2 would require my clients to use Eigen as well, not to mention potential problems with compatibility should they use a different version of Eigen (incidentally, Eigen is a header-only library if that matters). That leaves option 3.

What do folks think? Have I basically answered my own question? Any examples out there?

Related Questions

A related question was asked here but didn't really go into details of whether one should expose external types.

like image 294
plasma Avatar asked May 14 '12 01:05

plasma


2 Answers

Exposing the 3rd party libraries is the easiest in the short term, but will most likely to bite you in the back in the long term. Easiest, because the types are alrady there, you do not need to come up with your own. Will bite you if you would want to use a different implementation library in the future, or would want to allow expansion of the data the client passes to you.

Using only basic types is is almost like coming up with your own, but it's much lower level, for no good reason. Your users will have a hard time using your library without constantly refering to the documentation on what's what.

Using your own types is the best option if you want flexibility down the line. It might seem like a lot of work up front as you need to re-create all the already existing types, but if you give it some tought, you might find that if you use slightly different types in your library's interface, it will facilitate implementation change better later on.

So the answer really depends on your goals and long-term plans/predictions: if you don't see yourself ever changing from your current implementation, you can go with re-using the existing types, but if you foresee/plan change in the future, you should create your own independent interface.

like image 102
Attila Avatar answered Sep 26 '22 06:09

Attila


Wrap / encapsulate. Say you want to add some additional feature, such as caching the result of a computation, like the norm of a quaternion, as an implementation change. You can't do that (as easily) if you expose the 3rd party types without forcing your client code to change its call.

like image 41
djechlin Avatar answered Sep 26 '22 06:09

djechlin