您是正确的,内存大小是在编译时定义的,应用程序 B/C 将面临严重的内存损坏问题。
没有办法在语言级别明确地处理这个问题。您需要与操作系统合作以将适当的共享库提供给应用程序。
您需要对库进行版本控制。
由于没有明确的方法可以使用构建工具执行此操作,因此您需要使用文件名来执行此操作。如果您查看大多数产品,这大概就是它们的工作原理。
在 lib 目录中:
libD.1.00.so
libD.1.so -> libD.1.00.so // Symbolic link
libD.so -> libD.1.so // Symbolic link
现在在编译时指定 -lD 并链接到 libD.1.00.so,因为它遵循符号链接。在运行时,它知道使用这个版本,因为这是它编译时所针对的版本。
所以你现在将 lib D 更新到 2.0 版
在 lib 目录中:
libD.1.00.so
libD.2.00.so
libD.1.so -> libD.1.00.so // Symbolic link
libD.2.so -> libD.2.00.so // Symbolic link
libD.so -> libD.2.so // Symbolic link
现在,当您使用 -libD 构建时,它会链接到版本 2。因此,您重新构建 A,它将从现在开始使用 lib 的版本 2;而 B 和 C 仍将使用版本 1。如果您重建 B 或 C,它将使用新版本的库,除非您在构建 -libD.1 时明确使用旧版本的库
一些链接器不知道如何很好地遵循符号链接,因此有一些链接器命令可以提供帮助。gcc 使用“-install_name”标志你的链接器可能有一个稍微不同的命名标志。
作为运行时检查,将版本信息放入共享对象(全局变量/函数调用等)通常是一个好主意。因此,在运行时,您可以检索共享库版本信息并检查您的应用程序是否兼容。如果不是,您应该退出并显示相应的错误消息。
另请注意:如果将 D 的对象序列化到文件中。您知道需要确保维护有关 D 的版本信息。Libd.2 可能知道如何读取版本 1 D 对象(通过一些显式的工作),但反之则不成立。