我正在用两个超级旧程序代码A和代码B进行科学项目。两个代码之间的交互是通过二进制无格式数据。数据排列为每四个字节组合形成一个浮点数。这两个程序都是多年前编写的,开发人员现在在不同的机构中,很难联系。由于我需要紧急查看结果并且我的编程不是那么好,我使用与开发人员或modder相同的平台来编译和运行程序以避免调试问题。
代码A主要用C语言编写,其余部分用bash和FORTRAN编写。目前还不清楚开发人员在哪个平台上编写了这个程序,但我使用的是去年从毕业生那里传来的修改版本。学生在Windows中使用64位Cygwin修改了程序,我发现这是我可以编译并运行它而没有错误的唯一平台。例如,如果我在OSX,Ubuntu或32位Cygwin上运行它,由于我的编程时间和技能有限,我将遇到超出我能处理的范围的错误。
代码B在SunOS上用C语言编写,依赖于Sun Performance Library。同样,我只能在我们计算机实验室的古老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机器上的二进制无格式数据之间是否存在任何差异?如果有的话,有没有办法在没有修改源代码的情况下转换数据在这种紧急情况下/ *,因为它必须比进行任何调试快得多* /?
答案 0 :(得分:0)
不同的平台可以很容易地为基本数据提供不同的大小。
在32位和64位之间的cygwin上,数据大小存在差异 指针,长,长双。 尝试比较所有不同平台之间的程序输出:
$ cat size_of.c
#include <stdint.h>
#include <stdio.h>
#include <math.h>
int
main()
{
printf("sizeof(char) == %d\n", sizeof(char));
printf("sizeof(short) == %d\n", sizeof(short));
printf("sizeof(int) == %d\n", sizeof(int));
printf("sizeof(long) == %d\n", sizeof(long));
printf("sizeof(long long) == %d\n", sizeof(long long));
printf("sizeof(long long int) == %d\n", sizeof(long long int ));
printf("sizeof(float) == %d\n", sizeof(float));
printf("sizeof(double) == %d\n", sizeof(double));
printf("sizeof(long double) == %d\n", sizeof(long double));
printf("sizeof(wchar_t) == %d\n", sizeof(wchar_t));
printf("sizeof(u_long) == %d\n", sizeof(u_long));
printf("sizeof(ssize_t) == %d\n", sizeof(ssize_t));
printf("sizeof(size_t) == %d\n", sizeof(size_t));
void *p;
printf("sizeof(*void) == %d\n", sizeof(p));
return 0;
}
答案 1 :(得分:0)
如果Solaris机器是SPARC,那么除非程序小心地按指定的顺序格式化数据,否则大于一个字节的数字将以与英特尔CPU不同的顺序存储,因为您和#39 ;在您的Windows机器上找到。这称为 endianness 。
浮点数也可以用各种格式编写,但IEEE floating point standard可能就是这里使用的。当然,如果您想了解这些数据可能出现的限制和可能的错误,那么a lot more to know about how floating point numbers are handled就会出现。{/ p>