Solved

Distribution of C/C++ library header files with library

Posted on 2011-09-14
8
476 Views
Last Modified: 2012-06-21
I have a C++ library I am going to distribute upon completion.  Some of the header files for various classes have private variables which reference other code and require the developer to then include another header file in their code, or a cascade of header files if the referenced header is dependent on a host of others.

A good example of this would be a log file which uses an SqLite database as its storage mechanism.  The class opens the database once and it remains open until the class destructor is called.  Because the SqLite database object needs to remain open across calls to the methods of the class it is kept as a private class variable which requires #include <sqlite3.h> in the header file.

Is there a best practice or standard way of handling these sorts of situations?  I want to avoid items like forward declarations in the header file.  

I have thought about simply declaring such variables in the cpp body file, but it would not be encapsulated within the class in this approach, and I am not sure if there would be unintended  consequences of this approach.  

Another approach which does not seem elegant to me would be to create a second class to hold the private variables which then could be included in the cpp file without the need to put it in the header file.  Any approach I come up with seems to be clunky and non-standard.

Your help would be greatly appreciated.
Thanks.
0
Comment
Question by:edc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 36538879
The trick would be to encapsulate these dependencies and only provide an interface to the users that does not require any 3rd party headers. I prefer pure virtual interfaces for that approach. E.g.
// database_if.h - that's what the user sees

IDatabase* CreateDB();

struct IDatabase {

  virtual bool Open() = 0;

  //...

  virtual void Close() = 0;
};

// sqlite3_database_if.h - that's what you use (pseudocode)

#include <sqlite3.h>

class Sqlite3Database : public IDatabase{

public:

  virtual bool Open()  { return sqlite3_open();}

  //...

  virtual void Close() { sqlite3_close();}

private:
  sqlite3_db the_db;
};

IDatabase* CreateDB() { return new Sqlite3Database;}

Open in new window

0
 
LVL 7

Expert Comment

by:JimBeveridge
ID: 36539798
I would recommend that you distribute a shared library (.dll in Windows or .so in Linux) and instead of a static library .lib. When you deliver a shared library, you compile it, so you don't need to worry about end-users linking to missing libraries or relying on header files. A shared library *is* the best practice for this situation.

Of course, if your intention is to deliver source code to your end-users, then there's really no workaround because they need all of the the headers and 3rd party libraries to build your source. There's no issue with SQLite because it's Public Domain, but just about anything else you use is going to be copyright, which means that you aren't allowed to distribute the header files to those libraries.
0
 
LVL 1

Author Comment

by:edc
ID: 36540331
@jkr - I think this solution would actually take care of several aspects of the library which have been puzzling me.  

One question that has come up in my mind - although I think I know the answer, I would like to verify with you.  Would I have to export ( __declspec(dllexport) ) the Sqlite3Database class as well as the IDatabase class?

Thanks for you advice and help.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 36540365
No, not at all. The only function that would have to be exported that way would be the 'factory', in the above

IDatabase* CreateDB();
0
 
LVL 34

Expert Comment

by:sarabande
ID: 36542103
it is good practice to use forward declarations in the header files as far as possible so you should not try to avoid them.

i would assume you then could have the include for sqllite in the cpp file only.

normally a database interface could be designed with pointers and references only which both could declared in the header using forward declaration.

Sara
0
 
LVL 1

Author Comment

by:edc
ID: 36542663
@jkr.  Thanks very much.  Your advice is always appreciated :o).

@sarabande.  Thank you for your thoughts.  Forward declarations are good practice, but for a few reasons I really wanted a different way to handle it.

@JimBeveridge.  Be not alarmed.  It is being distributed as a dll/so and I am not trying to pull any fast ones in regards to licensing of third parties.  I am curious though how you would approach using a C/C++ library without the header files.  Are you thinking __declspec(dllimport)?
0
 
LVL 7

Expert Comment

by:JimBeveridge
ID: 36543603
I agree with jkr. You don't want to publish header files that include any member data, so abstract interfaces are the way to go. However, it's a bit of a rat's nest from there, because the memory manager in the DLL is separate from the memory management in your app, so you can't pass around string or CString unless they are "const", and even that often won't work unless your DLL exactly matches the compiler versions, header file versions, etc. of the app. Nor can you "new" an object in the DLL and "delete" the object in the app.

All of which is why COM exists.
0
 
LVL 1

Author Closing Comment

by:edc
ID: 36543645
Thank you everyone for providing your thoughts and experience.  I greatly appreciate it.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question