Click here to Skip to main content
15,867,985 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've been writing a library for awhile now but I've never been able to figure out how to make it so users don't have to include the headers for all the dependencies I'm using in my library. The problem is that my classes need to store pointers and data types from various dependencies which have to be defined before use.

I've tried defining basic abstract versions of these data types before use which works for most types but there are a few that give me errors like type redefinition or what ever. I also tried to use an #ifdef to only define these variables within the header when I'm compiling my library but when I try to use my library without those variables defined in the header I get undefined behavior where random stuff just bugs out. So how the heck do I use third party libraries inside my library without needing to include their headers?

Say in my library header I have this class:

C++
class __declspec( dllexport ) Myclass
{
public:
SDL_GLContext Context;
};


For anyone to include my header they would first need to include SDL. How can I store the context in my class without needing users of my library to include SDL?
Posted
Updated 11-Dec-12 10:15am
v3
Comments
Sergey Alexandrovich Kryukov 20-Aug-12 0:01am    
You are not hoping to get away without headers at all, aren't you?
If you could illustrate you idea on some minimal code sample (does not have to really work, it would be enough if it express your idea or requirements), it would be helpful.
--SA
Steven Batchelor 20-Aug-12 3:03am    
No, I have headers for my library but I don't want to have to include any headers from other dependencies.
enhzflep 20-Aug-12 3:17am    
in the example you've used here, I note particularly that you've got the data member as public. My memory is that the other libraries' functions get linked as needed into your library. You could test by removing your lirary's dependancies before building.

Your example above makes me wonder if your class may exposing more of it's internals than it should, leading to the need to declare certain types/functions as found in assorted header files.
Sergey Alexandrovich Kryukov 20-Aug-12 3:28am    
Thank you for clarification. Now you need to clarify the idea. Why would the user of your library use the declarations from other libraries? Did you try to wrap them in yours? What declarations would you like to pass to the users? One simple example based on one function per scenario could help...
--SA
Sergey Alexandrovich Kryukov 20-Aug-12 3:42am    
It looks like Solution 1 explains it all for you. For the record, please see also my last comment below...
I advise you to accept Solution 1 formally (green button).
--SA

1 solution

There are two methods to handle third-party includes:

a) put the #include of the third party header inside your own header

b) don't embed a full object of the third party, but just a pointer. In your case that would look like:

class SDL_GLContext;

class __declspec( dllexport ) Myclass
{
public:
    SDL_GLContext* pContext;
};


Then allocate the object inside your Myclass constructor. That way, you only need to make an advance declaration of the third-party class (first line in the code above).

There are two more techniques worth mentioning.

- on the Microsoft platform you can use #pragma directives inside your library code to save the users of your library the work of putting your library on the linker input list. For example
#pragma comment (lib, "MyLib.lib")


- use the so-called PIMPL technique (stands for pointer to pointer-to-implementation). This means: Declare just a single data member inside your class, which is a pointer to an implementation class. Then, in the .cpp file your declare an implementation class with all the member data you need. For example:

// in your .h file
class MyClassImpl;

class MyClass
{
public:
    // just declare those functions the external user is
    // allowed to see

private:
    MyClassImpl* m_pThis;
};

// in your .cpp file
class MyClassImpl
{
public:
    // here goes the implementation declaration of all the stuff
    // that should be hidded from the user
};

MyClass::MyClass()
{
     m_pThis = new MyClassImpl;
}
MyClass::~MyClass()
{
    delete m_pThis;
}


This is a nice technique to insolate your class and let the exterior only know the bare minimum about your class. Particularly: The external size of the class always stays the same (just the size of the pointer). That is very useful when your class is part of a library and the user allocates objects of your class in his own code. You may then add members to your implementation without having the user to recompile his entire code.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 20-Aug-12 3:41am    
Good reply, voted 5.
--SA
nv3 20-Aug-12 3:45am    
Thanks Sergey!
Sergey Alexandrovich Kryukov 20-Aug-12 3:43am    
OP is advised to accept it formally.
--SA
Steven Batchelor 20-Aug-12 3:48am    
I remembered hearing about the PIMPL technique before but I could not remember the name nor how it worked. Thank you!
nv3 20-Aug-12 3:50am    
Welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900