如何在构建时在 C++ 中包含 JSON 文件/对象

Posted

技术标签:

【中文标题】如何在构建时在 C++ 中包含 JSON 文件/对象【英文标题】:How to include JSON file/object inside C++ at build time 【发布时间】:2019-03-22 20:03:24 【问题描述】:

我有一个带有数据库环境配置的 JSON 文件,名为 env-config.json,如下所示:


"LATEST":
"DB_DATABASE":"databasename",
"DB_HOST":"hosturl",
"DB_PORT":"3306",
"DB_USER":"root",
"POOL_MAX":1
,
"PROD":
"DB_DATABASE":"databasename",
"DB_HOST":"hosturl",
"DB_PORT":"3306",
"DB_USER":"root",
"POOL_MAX":1


位于 c++ 项目的源代码的根目录中

所以我想以 json 格式轻松触摸该配置,但例如从我编译的 c++ 代码中使用它

程序运行时查询系统是什么环境,比如

system.getEnvironment()

系统显示“PROD”

在那一刻调用该 JSON 文件并提取信息以在程序中使用。

问题是我需要一种方法将 json 与最终可执行文件一起分发,我不能将二进制文件和 json 文件放在单独的文件中。

我尝试:

file (STRINGS "env-config.json" CONFIG)

add_definitions (-DENV_CONFIG=$CONFIG)

然后在程序中使用该字符串,但问题是 cmake 崩溃,因为 json 中的所有 scapes,是的,我可以将 json 放入带有很多 \n 和 scapes 的字符串格式,但我会丢失可读的 json 格式。

因此,例如可以让我的 json 文件以 json 格式保持完整,并在构建时 cmake 将其转换为字符串,然后使用

file (STRINGS "env-config.json" CONFIG)

add_definitions (-DENV_CONFIG=$CONFIG)

或者如果因为 JSON 格式那么复杂

可以使用 java 之类的属性文件

db-$env.properties

有这个内容

db.database.name = mydatabasename
db.database.url = myurl
db.database.user = root
db.database.password = root

并将它一起包含在可执行文件中,就像在配置类或结构中的 MAP 中一样

非常感谢!

【问题讨论】:

当然可以。您编写映射或字符串的声明,就像任何其他映射或字符串的声明一样,其中包含您想要包含的任何数据。因为这几乎是普通的 C++,所以真的不清楚你到底在问什么。 将文本添加到cpp文件中,然后根据配置进行切换。不要把配置当成宏,那样不好。 【参考方案1】:

我要么误解了您的用例,要么您错过了关于在构建时包含文件的重要一点。

如果我理解正确的话,拥有 JSON 配置文件的目的是让系统管理员能够随时配置应用程序。但是,在构建时将 JSON 文件注入应用程序意味着它将永远烘焙到可执行二进制文件中。 在 JSON 文件中发生更改的唯一方法是再次重建应用程序。

如果这是您想要的,我建议您简化生活并将配置作为头文件,您可以简单地将其包含在您的源代码(而不是 JSON)中,类似于:

config.h

#define LATEST_DB_DATABASE "databasename"
#define LATEST_DB_HOST     "hosturl"
#define LATEST_DB_PORT     3306
#define LATEST_DB_USER     "root"
#define LATEST_POOL_MAX    1

#define PROD_DB_DATABASE   "databasename",
#define PROD_DB_HOST       "hosturl"
#define PROD_DB_PORT       3306
#define PROD_DB_USER       "root"
#define PROD_POOL_MAX      1

如果这不可能,那么您需要使用任何语言编写构建脚本,该脚本读取 JSON 文件并将其转换为类似于所示的头文件,并且该头文件包含在源代码中并使用它进行编译。

但是,如果您不想在构建时包含 JSON 文件,那么您将需要一个用 C 编写的 JSON 库来在运行时读取配置文件。

【讨论】:

以上是关于如何在构建时在 C++ 中包含 JSON 文件/对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在进行广度优先搜索时在 Gremlin 中包含边?

C++ 两个派生类中包含彼此的对象(包括问题)

在 C++ 项目中包含 .idl 文件

Vue Cli 3 - 编译 Web 组件时在 dist 中包含 js 文件

Python setup.py 在 egg 中包含 .json 文件

在进行 ajax 调用时在 HTTP 标头中包含 JWT