简体   繁体   English

如何使C ++代码公共头文件内部?

[英]How to make a C++ code public headers internal?

I want to build a dll from my C++ code. 我想从我的C ++代码构建一个dll The problem is that the code has more than 200 .h header files that nearly all of them are public ; 问题是代码有超过200个.h头文件,几乎所有这些文件都是公开的 ; ie, 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. 也就是说,当我构建dll并且我想在另一个程序中使用它时,除了#include所需函数的头部之外,我还必须将用于构建dll所有头文件都提供给编译器。

I only need a few functions from the dll , but since nearly each header has #include d some other headers (ie, all headers are public) I have to give all of the header files to the compiler when using the dll library. 我只需要来自dll的一些函数,但由于几乎每个头都有#include d一些其他头(即所有头都是公共的)我必须在使用dll库时将所有头文件提供给编译器。

What is easiest way to come with just a few public headers to use with the dll ? 使用dll只需要几个公共头文件的最简单方法是什么? 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) 我试图用一些标题中的每个#include "xxxx.h替换它的源代码来使它们独立(公共)然后构建库,但是没有用(很多错误/太麻烦)。我不知道想要重写所有的标题。(@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? 例如,我可以以某种方式编写一个包含我所需函数的cpp文件和一个标题,然后使用以前构建的dll (包含所有标题),然后构建一个只有一个公共标题的新dll吗?

There are a few strategies to limit the number of (plublic) includes. 有一些策略可以限制(plublic)包含的数量。 The first is through forward declarations. 第一种是通过前瞻性声明。 The following is valid C++: 以下是有效的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 "xh" in "x.cpp". 然后在“x.cpp”中包含“xh”。 "yh" is no longer dependent on "xh", so "xh" could remain private (if necessary). “yh”不再依赖于“xh”,因此“xh”可以保持私密(如果需要)。 nifty, no? 好不好,不是吗?

But what do you do when X has to be a member of Y? 但是当X必须是Y的成员时你会怎么做? Typically, this is solved using the impl paradigm: 通常,这是使用impl范例解决的:

 //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#. 遗憾的是,这不是像C这样的非名称错误语言,也不是像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). 然后,你可以使用dll作为头文件(我已经过度简化,它在屁股上是一个巨大的痛苦,但如果你不需要实际的结构则可行)。

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: 最简单的方法是使用其中的所有标题创建一个中间c-plus-plus:

 //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. 不幸的是,这也将扩展所有stdlib标头...这将成为一个巨大的,不可读的文件。 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. 老实说,防止公共标头重载的唯一好方法是让它们首先不要发疯。

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. 还要为这些函数编写新的.c或.cpp文件。 In those functions in the .cpp file include the original headers and call the original functions. 在.cpp文件中的那些函数中包含原始标题并调用原始函数。

This should let you maintain API and ABI stability through code changes as well. 这应该可以让您通过代码更改来维护API和ABI的稳定性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM