我正在使用两个超级旧程序代码A和代码B进行科学项目。这两个代码之间的相互作用是通过二进制的无构造数据。数据被安排为每个四个字节组合以形成浮点数。这两个程序都是在许多年前编写的,而开发人员现在在不同的机构中,很难联系。由于我需要紧急看到结果以进行防御,而且我的编程不太好,因此我使用与开发人员或Modder相同的平台来编译和运行程序,以避免调试麻烦。
代码A主要用C编写,其余部分用Bash和Fortran编写。目前尚不清楚开发人员编写了该程序的哪个平台,但我使用的是去年毕业的学生通过的修改版本。该学生在Windows的64位Cygwin上修改了该程序,我发现这是我可以编译并运行它的唯一一个没有错误的平台。例如,如果我在OSX,Ubuntu或32位Cygwin上运行它,我将遇到错误的错误,因为我的编程时间有限和技能,我可以处理的范围。
代码B用Sunos的C编写,并依赖于Sun Performance库。同样,我只能在计算机实验室中的一台古董Solaris机器上成功编译并运行它。在其他平台上,我有大量缺失的标题,收集所有标题非常麻烦。根据文档,代码B使用代码A的输出二进制数据,该格式以完全相同的方式排列。如果我将输出数据从代码A复制到代码B并运行它,则代码B正在抱怨数据/*屏幕输出的有效性:检测到的负值!*/。但是,如果我使用目录中提供的示例数据 - 开发人员用来编写和测试他的程序的数据。
首先,如果我尝试仅采用代码B的数据阅读功能,请创建一个简单的C项目并将其称为Main()函数,我发现在IDE中,我无法重现该错误。原始代码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 ", vmfile);
perror(msg);
return 2;
}
/* checking validity codes go here */
close(fildes);
该功能正确地读取了我的二进制未形成数据,但未正确读取开发人员的数据。这与试图在Solaris上编译项目时发生的情况相反。
其次,我尝试绕过代码B的数据阅读功能,编写一个新功能,以通过ASCII文件在数据中读取,并确保存储数据的数组将返回到Main()函数。进行此修改后,数据被正确但出乎意料地加载,在加载数据后,该程序停止并增加了分段故障,而在使用开发人员的示例数据运行时从未见过。我不确定我是否应该继续处理这个新错误或放弃这个想法。
那么,在32位和64位平台,Linux和Windows,Solaris和其他Linux机器上的二进制数据之间是否存在任何差异?如果有的话,是否有任何方法可以在此紧急情况下/*中修改源代码而不修改源代码,因为它必须比进行任何调试 */?
如果Solaris Machine是SPARC,则除非程序谨慎地按指定顺序格式化数据,否则大于字节的数字将以与英特尔CPU不同的顺序存储正如您在Windows机器上找到的那样。这称为 endianness 。
浮点数也可以以多种格式编写,但是IEEE浮点标准可能是这里使用的。当然,如果您想了解此类数据可能会看到的局限性和可能的错误,那么还有很多要了解的浮点数。
不同的平台可以很容易地具有不同的大小来实现基本数据。
已经在32至64位之间的Cygwin上的数据大小差异在指针上,长长的双倍。尝试比较所有不同平台之间的类似程序输出:
$ cat size_of.c
#include <stdint.h>
#include <stdio.h>
#include <math.h>
int
main()
{
printf("sizeof(char) == %dn", sizeof(char));
printf("sizeof(short) == %dn", sizeof(short));
printf("sizeof(int) == %dn", sizeof(int));
printf("sizeof(long) == %dn", sizeof(long));
printf("sizeof(long long) == %dn", sizeof(long long));
printf("sizeof(long long int) == %dn", sizeof(long long int ));
printf("sizeof(float) == %dn", sizeof(float));
printf("sizeof(double) == %dn", sizeof(double));
printf("sizeof(long double) == %dn", sizeof(long double));
printf("sizeof(wchar_t) == %dn", sizeof(wchar_t));
printf("sizeof(u_long) == %dn", sizeof(u_long));
printf("sizeof(ssize_t) == %dn", sizeof(ssize_t));
printf("sizeof(size_t) == %dn", sizeof(size_t));
void *p;
printf("sizeof(*void) == %dn", sizeof(p));
return 0;
}