我已经编写了一个基于其他几个库的C++共享库。 现在,当使用库时,我得到了很多关于'foreign'库函数的未定义参考。编译和链接工作正常,如果我明确地将'外部'库添加到g ++命令。有没有办法解决这个问题,以便图书馆用户不必手动链接到“外国”图书馆?共享库中的外部库
感谢您的帮助。
我已经编写了一个基于其他几个库的C++共享库。 现在,当使用库时,我得到了很多关于'foreign'库函数的未定义参考。编译和链接工作正常,如果我明确地将'外部'库添加到g ++命令。有没有办法解决这个问题,以便图书馆用户不必手动链接到“外国”图书馆?共享库中的外部库
感谢您的帮助。
如果您不希望共享库的用户必须声明库的所有链接时依赖关系,则可以在构建共享库本身时通知链接器已经存在这些依赖关系。
,在Makefile中,这应该是这样的:
mylib.so:
g++ -o mylib.so $OBJS -llib1 -llib2 -llib3
随后的mylib.so
用户并不需要指定lib1
,lib2
或lib3
,但他们仍然需要可(在正确的版本)以使程序能够运行。
您应该从发布(导出)界面中排除所有外部数据类型和函数。这意味着,对于GCC,您可以使用-fvisibility=hidden
来隐藏所有实施细节,因此,仅导出零件与attribute ((dllexport)。 Pimpl成语(aka Opaque pointer)可以帮助您从已发布的头文件中删除依赖项。下面 简单的例子:
#include<memory>
#if EXPORT_DLL
#define DLL_PREFIX __attribute__ ((dllexport))
#else
#define DLL_PREFIX __attribute__ ((dllimport))
#endif
class XImpl;
class DLL_PREFIX X {
//...
private:
std::unique_ptr<XImpl> impl_;
}
定义并实现XImpl
在另一头/来源,仅此而已。没有来自其他库的链接依赖关系,只有你自己。但运行时依赖依然存在!
感谢您的回复,但我不明白这一点。假设我的库的接口类是iface.hpp,并且实现位于iface.cpp中(在此文件中调用外部库)。我将如何实施您的解决方案? – user1801173
您的iface.hpp将包含'X'定义和'XImpl'的前向声明(正如我提到的erarlier),iface.cpp可能包含'XImpl'定义或者包含外部头文件,因此您可以使用init和'impl_'字段并通过它转发所有方法。例如,如果你的X包含了一些'void f()'的方法,那么你应该向XImpl中添加类似的方法,并在iface.cpp中调用它,同时从接口类实现'f()'来做实际的工作。 –
好吧,所以我写了一个新类将所有调用转发给iface类。但是iface中的一些函数调用具有由外语提供的类型的参数。因此,我将不得不包含相关的标题。然后我在同一点? – user1801173