Reputation: 317
I want to build a dll
from my C++ code. The problem is that the code has more than 200 .h
header files that nearly all of them are public; i.e., when I build the dll
and I want to use it in another program, in addition to #include
ing the headers of the needed functions, I have to give all of the header files that were used for building the dll
to the compiler.
I only need a few functions from the dll
, but since nearly each header has #include
d some other headers (i.e., all headers are public) I have to give all of the header files to the compiler when using the dll
library.
What is easiest way to come with just a few public headers to use with thedll
? I tried to replace each #include "xxxx.h
with it's source code in some headers to make them stand-alone (public) and then built the library, but didn't work (many errors/ too cumbersome). I don't want to rewrite all of the headers. (a solution was suggested in this comment by @Angew)
For example, can I somehow write a cpp file containing my needed function and a header for it, and then use the previously built dll
(with all of the headers) and then build a new dll
with just one public header from it?
Upvotes: 2
Views: 1607
Reputation: 7881
There are a few strategies to limit the number of (plublic) includes. The first is through forward declarations. The following is valid C++:
struct X;
struct Y
{
Y(); ~Y();
X foo();//yes this is legal, as long as it is included before you call this function
void bar(X&); //(with or without const)
void baz(X*);//(with or without const)
//use smart pointers if you know whats good for you
X* x;
std::vector<X> y;//Warning! X needs to be defined before destructor/default constructor!
};
And then include "x.h" in "x.cpp". "y.h" is no longer dependent on "x.h", so "x.h" could remain private (if necessary). nifty, no?
But what do you do when X has to be a member of Y? Typically, this is solved using the impl paradigm:
//y.h (public header file)
#ifndef Y_H
#define Y_H
class Y
{
public:
Y();
~Y();
void foo();
protected://or private, w/e
class Y_impl;
Y_impl* impl_;
};
#endif
//y-impl.h
//private header file
#ifndef Y_IMPL_H
#define Y_IMPL_H
#include "y.h"
#include "x.h"
class Y::Y_impl
{
public:
void foo();
private:
X x;
};
#endif
//y.cpp (private source file)
//i typically put both y and y impl definitions here, but you could split em up
#include "y.h"
#include "y-impl.h"
Y::Y() { impl_ = new Y();}
Y::~Y() { delete impl_;}
void Y::foo() {impl_->foo();}
void Y::Y_Impl::foo() {/*do something*/}
This is unfortunately not a non-name mangled language like C, or a high-level, self-inspecting language like C#. Then, you could use the dll as a header file (i'm over simplifying, its a huge pain in the ass, but doable if you don't need the actual structures).
Compiling all these headers into one giant header:
SUCH A BAD IDEA. But we'll go with it.
The easiest way would be to make a intermediate c-plus-plus with all the headers in it:
//something.cpp
#include "x.h"
#include "y.h"
and then get the compiler to dump a debug after expanding the includes. Unfortunately, this will also expand all stdlib headers as well...this will make an enormous, unreadable file. It will be included in its entirety in any compilation unit, slowing your compilation time to almost infinite.
Honestly, the only good way to prevent public header overload is to keep them from going crazy in the first place.
Upvotes: 2
Reputation: 54325
Create a documented, well defined interface.
This means writing a new header file with new functions in it. Also write a new .c or .cpp file for those functions. In those functions in the .cpp file include the original headers and call the original functions.
This should let you maintain API and ABI stability through code changes as well.
Upvotes: 1