我想从我的C ++代码构建dll
。问题是该代码有超过200个.h
头文件,几乎所有头文件都是公开的;即,当我构建dll
并且我想在另一个程序中使用它时,除了#include
所需函数的头部之外,我还必须提供所有用于的头文件构建dll
到编译器。
我只需要dll
中的一些函数,但由于几乎每个标题都有#include
d个其他标题(即所有标题都是公共的),我必须提供所有的头文件使用dll
库时的编译器。
使用dll
时只需要几个公共标题,最简单的方法是什么?我尝试用一些标题中的每个#include "xxxx.h
替换它们的源代码以使它们独立(公共)然后构建库,但是没有用(许多错误/太麻烦)。我不想重写所有的标题。 (this comment @Angew提出了一个解决方案)
例如,我可以以某种方式编写一个包含我所需函数的cpp文件及其标题,然后使用以前构建的dll
(包含所有标题),然后构建一个新的{{1}只有一个公共标题?
答案 0 :(得分:2)
有一些策略可以限制(plublic)包含的数量。第一种是通过前瞻性声明。以下是有效的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!
};
然后在“x.cpp”中包含“x.h”。 “y.h”不再依赖于“x.h”,因此“x.h”可以保持私有(如有必要)。好不好,不是吗?
但是当X必须是Y的成员时你会怎么做?通常,这是使用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*/}
遗憾的是,这不是像C这样的非名称错误语言,也不是像C#这样的高级自我检查语言。然后,你可以使用dll作为头文件(我过度简化,它是一个巨大的痛苦,但如果你不需要实际的结构,可行。)
将所有这些标头编译成一个巨型标头:
这是一个不好的想法。但我们会坚持下去。最简单的方法是制作一个包含所有标题的中间c-plus-plus:
//something.cpp
#include "x.h"
#include "y.h"
然后让编译器在扩展包含后转储调试。不幸的是,这也将扩展所有stdlib标头...这将成为一个巨大的,不可读的文件。它将完整地包含在任何编译单元中,从而将编译时间减慢到几乎无限。
老实说,防止公共标头重载的唯一好方法是让它们首先不要发疯。
答案 1 :(得分:1)
创建一个记录良好,定义明确的界面。
这意味着在其中编写带有新功能的新头文件。还要为这些函数编写新的.c或.cpp文件。在.cpp文件中的那些函数中包含原始标题并调用原始函数。
这可以让你通过代码更改来维护API和ABI的稳定性。