将 boost 与自己的标头和源代码链接
Posted
技术标签:
【中文标题】将 boost 与自己的标头和源代码链接【英文标题】:Linking boost with own headers and source code 【发布时间】:2014-06-17 09:29:35 【问题描述】:我正在使用 boost 库和 opencv,现在我必须实现我自己的头文件和源代码(除了 main.cpp),这也需要这些库。 main.cpp 看起来像(原则上):
// STL includes
#include <stdlib.h>
...(some other STL stuff)
// Boost includes
#include <boost/array.hpp>
...(a lot of other boost stuff)
//OpenCV
#include <opencv2/opencv.hpp>
// Own header files
#include <myHeader.hpp>
main() do_some_stuff;
如果我在 myStuff.hpp 中没有与 boost 相关的任何内容,则此方法有效。但是如果我在其中添加一些东西(函数描述在 myStuff.cpp 中),例如:
class aClass
public:
aClass(int);
void doSomething(boost::shared_ptr<int>);
void doSomethingElse(cv::Mat);
;
然后它显示'boost' had not been declared
或'cv' does not name a type
。
我当时想,好吧,我也只需要在这个文件中包含标题,所以我添加了相同的包含,但是当它尝试链接时会出现很多错误,例如:
/usr/include/boost/operators.hpp:308:35: error: expected identifier before numeric constant
/usr/include/boost/operators.hpp:308:35: error: expected ‘>’ before numeric constant
/usr/include/boost/operators.hpp:310:1: error: expected class-name before ‘’ token
/usr/include/boost/operators.hpp:311:3: error: expected unqualified-id before numeric constant
...(a lot more of these errors)
我正在使用 Makefile 来构建这个项目,它看起来像:
OPENCV_I = `pkg-config --cflags opencv`
#it finds boost without any additional -I or -L options...
INCLUDEPATHS = $(OPENCV_I)\
-I.\
-L.
LIBS=-lGL -lGLU -lm -lboost_program_options -lboost_system -lboost_thread -pthread -lrt -lopencv_core -lopencv_highgui
SRCCXX := main.cpp myStuff.cpp
OBJSCXX := $(SRCCXX:%.cpp=$BUILDDIR/%.o)
$(BUILDDIR)/%.o : %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDEPATHS) -c $< -o $@ -DdDOUBLE $(LIBS)
all: $OBJSCXX
$(CXX) $(LDFLAGS) $(INCLUDEPATHS) -o $(OUTNAME) $? -DdDOUBLE $(LIBS)
以前我使用 CMake,它在这类项目中运行良好,只是这个项目是一个更大项目的一部分,他们使用 Makefiles 处理所有事情。所以我想主要问题是makefile,可能当我列出我的源代码SRCCXX := main.cpp Visualisation.cpp
它不喜欢它...
有什么建议么?
提前谢谢你。
编辑..................................................
所以我的整个 myStuff.hpp 看起来像:
#define _USE_MATH_DEFINES
#include <math.h>
#define RINGS 5
#define SECTIONS 12
// Boost includes
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/assign/ptr_list_of.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/program_options.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <opencv2/opencv.hpp>
class Sensor
public:
Sensor(int);
void Update(boost::shared_ptr<char[RINGS][SECTIONS]>);
int Id();
private:
char data[RINGS][SECTIONS];
int id;
;
还有 myStuff.cpp:
#include "myStuff.hpp"
void Sensor::Update(boost::shared_ptr< char[RINGS][SECTIONS] > buffer)
for(int i=0;i<RINGS;i++) for(int j=0;j<SECTIONS;j++) data[i][j]=buffer[i][j];
;
Sensor::Sensor(int a)
id=0;
;
int Sensor::Id()
return id;
;
还有我的 main.cpp:
// STL includes
#include <stdlib.h>
#include <iostream>
#include <mutex>
#include <string.h>
#include <typeinfo>
#include <queue>
#include <memory>
// Boost includes
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/assign/ptr_list_of.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/program_options.hpp>
#include <boost/numeric/ublas/matrix.hpp>
//OpenCV
#include <opencv2/opencv.hpp>
// Own header files
#include "myStuff.hpp"
////////////////////////////////////////// Main
int main (int argc, char **argv)
Sensor sensor(0);
return 0;
【问题讨论】:
显示第 308-311 行的完整代码。 您是否也在myStuff.hpp
中添加必要的内容?
我删除了链接器标记,因为您仅在此阶段遇到编译问题。
是的,我做内含物。
你的意思是-L。作为链接器标签?
【参考方案1】:
首先要做的事情...当在您的项目中包含您自己的标头时,我建议您使用"mine.hpp"
而不是<mine.hpp>
。这可以确保编译器不会搜索完整的包含路径并意外找到一些其他同名包含(例如不同的版本)。
其次,当您在一个类中有一个依赖项时,您可以在该类中包含该依赖项的标头。您不能假设某人会将您的所有依赖项包含在主类或其他类中。有时有人只想单独使用你的类。您不希望他们必须弄清楚您的依赖关系。不要担心复制,因为包含保护(或pragma
)会阻止复制。
至于您的特定问题,您需要使用您的代码。那时您当然已经成功地正确包含了您的标题。我猜想它们可能源于某处缺少 或
;
。查看您的第一个错误并解决该错误。
编辑
问题似乎与您使用 boost 的方式有关。我查看了operators.hpp 和版本1_44 中的内容,我看到的是一个带有4 个模板参数的结构定义,其中一个默认为boost::detail::empty_base<T>
。我只能说确保你的整个 boost 库都在你的包含路径和链接路径上。
EDIT2
从您新发布的代码中,我发现了一些问题。首先是你的标题中有太多的包含。您应该只在头文件中包含类依赖项,并且总是更喜欢将头文件放入您的实现 (.cpp) 文件中。这有助于防止编译时间过长。因此,首先修改您的标题以仅包含您需要的依赖项:
#include <boost/shared_ptr.hpp>
#define RINGS 5
#define SECTIONS 12
class Sensor
public:
Sensor(int);
void Update(boost::shared_ptr<char[RINGS][SECTIONS]>);
int Id();
private:
char data[RINGS][SECTIONS];
int id;
;
然后在您的实现中,唯一的更改是在您的 for 循环周围放置大括号(这是为了清晰和安全......了解为什么将它放在一行但不值得)。还要把你的 CTOR 放在第一位:
#include "myStuff.hpp"
Sensor::Sensor(int a)
id=0;
;
void Sensor::Update(boost::shared_ptr< char[RINGS][SECTIONS] > buffer)
for(int i=0;i<RINGS;i++)
for(int j=0;j<SECTIONS;j++)
data[i][j]=buffer[i][j];
;
int Sensor::Id()
return id;
;
主要
#include "myStuff.hpp"
int main (int argc, char **argv)
Sensor sensor(0);
return 0;
您需要的唯一依赖项是boost::shared_ptr
。不过说实话,我很确定你也不需要那个。无论如何,我建议您从上述内容开始,然后一次添加一个依赖项。
【讨论】:
感谢您的回答。我据此更改了包含。不幸的是,所有错误都指向 boost 标头,例如/usr/include/boost/operators.hpp:308:35: error: expected identifier before numeric constant /usr/include/boost/operators.hpp:308:35: error: expected ‘>’ before numeric constant
您需要在代码中显示您使用 boost 库的代码。
到目前为止,我什至没有使用它,我只是在声明中使用它,例如:void doSomething(boost::shared_ptr<int>);
,然后在 myStuff.cpp 我有:void aClass::doSomething(boost::shared_ptr< int > data) ;
@Ferruccio 很抱歉这些天在 Java 和 C++ 之间切换。我的意思是包含路径。
main.cpp、myStuff.hpp和myStuff.cpp在同一个目录【参考方案2】:
几个小时后,我想通了。 myStuff.cpp 还需要包含标头。愚蠢的错误,但为什么编译器不能说诸如未定义或找不到之类的东西,而不是几页乱七八糟的错误......?
感谢您的帮助。
【讨论】:
看看我的更新。您应该只将绝大多数包含在 CPP 文件中(而不是在标题中)。以上是关于将 boost 与自己的标头和源代码链接的主要内容,如果未能解决你的问题,请参考以下文章
Boost Multiindex:示例在 cpp 文件中编译,但不在标头中
不带 -I 标志的链接 Boost 标头(来自 nuwen.net 的 MinGW Distro)