Solved

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

Posted on 2011-09-14
8
462 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
  • 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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
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 33

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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
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…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

786 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