C++ 将数据转换为C头作为二进制存储的方式

C++ 将数据转换为C头作为二进制存储的方式,c++,serialization,graphics,3d,C++,Serialization,Graphics,3d,在图形学中,有很多关于创建用于存储3d资源的自定义二进制文件格式的讨论,以便更常见的基于文本的格式(如OBJ和COLLADA)不必在运行时进行解析。有道理 然而,实际上并不简单的是二进制文件的创建,因为它涉及到诸如序列化或其他方法的技术,其中一些甚至不是由C++所固有地处理,除了可能在其最新的变型中。 但我突然想到,如果我将其中一种基于文本的格式解析为C样式的头,其中数据被简单地解析为float或struct声明,那么这些数据将与应用程序的其余部分一起编译成二进制。也就是说,解析是在应用程序之外

在图形学中,有很多关于创建用于存储3d资源的自定义二进制文件格式的讨论,以便更常见的基于文本的格式(如OBJ和COLLADA)不必在运行时进行解析。有道理

然而,实际上并不简单的是二进制文件的创建,因为它涉及到诸如序列化或其他方法的技术,其中一些甚至不是由C++所固有地处理,除了可能在其最新的变型中。 但我突然想到,如果我将其中一种基于文本的格式解析为C样式的头,其中数据被简单地解析为

float
struct
声明,那么这些数据将与应用程序的其余部分一起编译成二进制。也就是说,解析是在应用程序之外完成的,可能是通过脚本完成的,然后在编译时处理到二进制的转换,因为翻译单元包括头


我的想法正确吗?这与实际创建二进制文件格式并执行该路线相比如何

把编译时间等等放在一边,你把资源打包成单独文件的第一个、最大的和最主要的原因搞砸了——它们是外部的,可以交换。用这种头格式创建任何类型的DLC几乎是不可能的


您的方式将在每次资源更改时强制重新编译相关的项目部分,而将它们外部化将解析移动到运行时。艺术家可以处理他们的模型、纹理和其他一切,而开发人员则可以处理代码,而不会妨碍彼此。

您的想法绝对正确:您可以使用编译器的帮助将文本表示转换为二进制。我不使用头,而是将数据放在一个单独的翻译单元中,并保留一个固定的头,其中包含由脚本填充的数据结构的前向声明:

标题:

// This is fixed
extern float data_array[];
extern size_t data_array_cnt;
CPP文件:

// This gets generated by a script
float data_array[] = {1.2, 3.4, 5.6, 7.89 };
size_t data_array_cnt = sizeof(data_array)/sizeof(float);
这两种方法之间最大的区别在于,在文件中保留二进制表示可以让您在编译完所有内容后修改所表示的内容。事实上,您可以在生产中交换另一个二进制文件,它将立即生效。相反,每当二进制数据需要更改时,编译器路由会强制您重新编译程序:实际上,二进制数据会“烘焙”到程序的内容中


在支持动态链接的环境中,您可以通过将二进制数据隔离在单独的动态链接库中,并从“主”代码中单独编译该库,来实现一个中间解决方案。二进制数据仍然是代码的一部分,但现在您可以独立于程序的其余部分交换新的数据。

您所说的“DLC”是什么意思?@SebbyJohanns。正如dasblinkenlight已经说过的,从技术上讲,你可以将它们都链接到一个动态库中,但这仍然是一件非常痛苦的事情。我很好奇“DLC”到底代表什么,但我设法找到了它的含义。你能澄清一下这句话吗:“我会使用常规的C/C++文件(标题将保持固定,在编译之前由脚本填充数据结构的前向声明)。“C标题实际上是一个C文件,不是吗?或者你是说将数据放入翻译单元,而不是标题文件?标题文件保持“固定”是什么意思?@SebbyJohanns,从技术上讲,是一个“翻译单元”已包含标题,因此您可能对术语有点误解。他说的是,您可以将数据放入源文件,而不是标题,以减少重新编译依赖项和/或将源文件外部化到外部动态库中。@SebbyJohanns请用一个简短的示例查看编辑。