【发布时间】:2017-02-28 22:29:56
【问题描述】:
我正在用两个超级老程序代码 A 和代码 B 做一个科学项目。这两个代码之间的交互是通过二进制无格式数据。数据排列为每四个字节组合成一个浮点数。这两个程序都是多年前编写的,开发人员现在在不同的机构,很难联系。由于需要紧急看结果进行防御,而且我的程序不是很好,所以我使用与开发者或modder相同的平台来编译和运行程序,以避免调试麻烦。
代码 A 主要是用 C 编写的,其余部分是用 bash 和 FORTRAN 编写的。目前尚不清楚开发人员在哪个平台上编写了此程序,但我使用的是去年毕业的学生传递的修改版本。学生在 Windows 的 64 位 Cygwin 上修改了程序,我发现这是唯一一个我可以编译和运行它而不会出错的平台。例如,如果我在 OSX、Ubuntu 或 32 位 Cygwin 上运行它,由于我的时间和编程技能有限,我会遇到超出我可以处理范围的错误。
代码 B 在 SunOS 上用 C 语言编写,依赖于 Sun 性能库。同样,我只能在我们计算机实验室的一台老式 Solaris 机器上成功编译和运行它。在其他平台上,我有大量丢失的标题,收集所有标题非常麻烦。根据文档,代码 B 使用代码 A 的输出二进制数据,格式排列方式完全相同。如果我将输出数据从代码 A 复制到代码 B 并运行它,代码 B 会抱怨数据的有效性 /* 屏幕输出:检测到负值! */.尽管如此,如果我使用其目录中提供的示例数据(开发人员用来编写和测试他的程序的数据),代码 B 的运行没有问题。
首先,如果我尝试只使用代码B的数据读取功能,创建一个简单的C项目并在我的main()函数中调用它,我发现在我的IDE中我无法重现该BUG。原代码B中的数据读取算法如下:
int i, nxyz, fildes;
char msg[1024];
nxyz = nx * ny * nz;
if ((fildes=open(vmfile, O_RDONLY, 0664)) <= 1)
{
perror(vmfile);
return 1;
}
if (read(fildes, vmodel, nxyz*sizeof(float)) < 0)
{
sprintf(msg, "Reading %s\0", vmfile);
perror(msg);
return 2;
}
/* checking validity codes go here */
close(fildes);
该函数正在正确读取我的二进制未格式化数据,但未正确读取开发人员的数据。这与尝试在 Solaris 上编译项目时发生的情况相反。
其次,我尝试绕过代码B的数据读取函数,编写一个新函数通过ASCII文件读取数据,并确保存储数据的数组正确返回给main()函数。进行此修改后,数据正确加载,但出乎意料的是,在加载数据后,程序立即停止并引发了一个分段错误,这在使用开发人员的示例数据运行时从未见过。我不确定是否应该继续处理这个新错误或放弃这个想法。
那么,二进制无格式数据在 32 位和 64 位平台、Linux 和 Windows、Solaris 和其他 Linux 机器上是否有任何区别?如果有的话,在这种紧急情况下,有什么方法可以在不修改源代码的情况下转换数据 /* 因为它必须比任何调试都快得多 */?
【问题讨论】:
标签: c binary cygwin solaris sunos