如何将 #defines 从 C++ 共享库导出到应用程序
Posted
技术标签:
【中文标题】如何将 #defines 从 C++ 共享库导出到应用程序【英文标题】:How to export a #defines from c++ shared library to application 【发布时间】:2019-02-28 05:14:11 【问题描述】:我的库是在启用一些#define
的情况下构建的(例如-DUSE_FOO=1
),并且USE_FOO
也用于公共头文件。
问题是使用库的应用程序包含公共头文件,因此USE_FOO
出现在应用程序上下文中,并且在应用程序上下文中未定义。
如何根据库中是否启用 USE_FOO
定义将其导出到应用程序?
例如
include/public/foo.h
lib/libfoo.so --> foo.cc
in foo.h contain code as
#if defined (USE_FOO)
#define SIZE 5
#else
#define SIZE 10
#endif
foo.cc
#include "foo.h"
int getSizeFromLib()
return SIZE;
libfoo.so
源文件包含foo.h
并通过在编译时配置USE_FOO
构建。
现在,应用程序通过包含 public/foo.h
来使用 libfoo 库,并使用他自己的构建配置来构建应用程序。但问题是应用程序不知道USE_FOO
在应用程序端将始终未定义。所以SIZE
在应用程序中是 10,但在库中是 5
我希望 USE_FOO
根据是否为 libfoo.so
定义而导出到应用程序。即如果libfoo.so
是用USE_FOO=1
构建的,应用程序也应该看到USE_FOO=1
,反之亦然
如果无法以预定义的方式进行,那么任何解决此问题的技巧都会受到欢迎。
【问题讨论】:
共享库没有类似于#define 的内容。您需要自己处理编译标志。 【参考方案1】:在 Linux 世界中,此任务由 pkgconfig 工具解决。基本上除了二进制文件和头文件之外,您的库还附带一个 .pc
文件,看起来像
prefix=/usr/local
exec_prefix=$prefix
includedir=$prefix/include
libdir=$exec_prefix/lib
Name: foo
Description: The foo library
Version: 1.0.0
Cflags: -I$includedir/foo USE_FOO=1
Libs: -L$libdir -lfoo
这个文件安装到/usr/lib/pkgconfig
,客户端应该通过从Makefile调用pkg-config
来查询正确的CFLAGS
:
CFLAGS = -g -Wall -Wextra $(pkg-config --cflags)
更多详情,请查看guide。
唯一的可移植解决方案是添加一个自动生成 foo-config.h
标头,该标头将包含在所有库公共标头中,并将定义所有特定于版本的定义(如USE_FOO
)。这当然只适用于实际包含库头文件的源文件。
【讨论】:
【参考方案2】:无法将预处理器定义从库“导出”到应用程序。两者都必须使用兼容的标志进行编译,例如:
CFLAGS=-DUSE_FOO=1
gcc $CFLAGS --shared -o lib/libfoo.so foo.cc
gcc $CFLAGS lib/libfoo.so app.c
【讨论】:
“无法从库中导出预处理器定义”——至少在 Linuxpkg-config
上会这样做。以上是关于如何将 #defines 从 C++ 共享库导出到应用程序的主要内容,如果未能解决你的问题,请参考以下文章
WebAssembly:将命名空间从 C++ 库导出到 JavaScript
在 C++ 中创建 Windows 共享库时如何实现接口隔离
从 Linux 动态库/Linux 控制台应用程序导出/导入 C++ 函数 | Visual Studio Linux 项目