将c++代码从32位机器迁移到64位机器
migration c++ code 32 bit machine to 64 bit machine
我正在处理非常传统的代码,即从32位迁移到64位机器。我通常会用在32位运行良好但在64位机器中有问题的数据写入文件。当我检查文件时,发现它通常包含32位值的4除法。我的意思是,如果我们在32位机器中有80个值,那么在64位机器中就会有20个值。(大多数情况下)。我已经研究了下面的一段代码,但无法理解其中的一些功能。
-
为什么我们在写入File之前调用reverse函数。
-
反向函数的目的是什么。
-
在write函数中,尽管我们有任何数据类型,但我们总是写one_ascii值。
我试着用一些代码来帮助我简单地解释这个问题。请让我知道是否需要提供更多信息。
class GdsHeader
{
public:
unsigned short rlen;
char record_type;
char data_type;
};
class GdsRecord
{
public:
#ifndef SWIG
union
{
short *two_int;
int *four_int;
double *eight_real;
char *one_ascii;
// void *v;
};
#endif
int length;
GdsRecord (); // { v = 0; length = 0; }
~GdsRecord () ;// { delete v; }
void len (int l, int type);
};
class GdsBlock
{
bool valid_block ();
int len;
public:
bool record_unred;
int header_ftell;
GdsHeader h;
GdsRecord r;
int array_size;
// bool re_read;
// GdsBlock () { re_read = false; }
GdsBlock () { record_unred = false; header_ftell = 0; }
void set (int rt, int dt, int sz)
{TBE;
h.record_type = rt; h.data_type = dt;
array_size = sz; r.len (sz, dt);TBX;
}
int read_header (FILE *);
void read_block (FILE *);
void write (FILE *);
void prt ();
};
void GdsRecord :: len (int l, int type)
{
switch (type)
{
case STREAM_Bit_array:
case STREAM_Short: l *= 2; break;
case STREAM_Long: l *= 4; break;
case STREAM_Double: l *= 8; break;
}
if (l > length)
{
l = ((l / 8) + 2) * 8;
if (one_ascii) delete [] one_ascii;
one_ascii = new char[l];
debug2.printf("GdsRecord::len new one_ascii len %d one_ascii %Xn",l, one_ascii);
length = l;
}
}
#ifndef sparc
static void reverse (int len, char *buf)
{
TBE;
char tmp[24];
int i;
for (i = 0; i < len; i++) tmp[i] = buf[i];
for (i = 0; i < len; i++) buf[i] = tmp[ (len - 1) - i];
TBX;
}
inline void reverse (int len, short *s) { reverse (len, (char *) s); }
inline void reverse (int len, int *s) { reverse (len, (char *) s); }
inline void reverse (int len, double *s) { reverse (len, (char *) s); }
inline void reverse (int len, unsigned char *s) {reverse (len, (char *) s); }
#endif
void GdsBlock :: write (FILE *outstr)
{
TBE;
debug.printf("GdsBlock::write %Xn",outstr);
int i, err;
char *c, tmp;
if (h.data_type == 3)
{
cout<<"Begin...blk.r.four_int[0] =>"<<r.four_int[0]<<endl;
}
if (!this)
error.printf_exit("GdsBlock::write error !thisn");
if (!outstr)
error.printf_exit ("GdsBlock::write Error - outstr == 0n");
err = ferror(outstr);
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
if (err)
{ {
char *s = strerror (err);
fclose (outstr);
error.printf_exit ("GdsBlock::write error - %s, errno %dn", s, err);
}
switch(h.data_type)
{
case 0: /* NO DATA */
h.rlen = 4;
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
break;
case 1: /* BIT ARRAY */
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
#ifndef sparc
reverse (2, &r.two_int[0]);
#endif
h.rlen = (2 * array_size) + 4;
break;
case 2: /* TWO BYTE SIGNED INTEGER */
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
#ifndef sparc
for (i = 0; i < array_size; i++) reverse(2,&r.two_int[i]);
#endif
h.rlen = (2 * array_size) + 4;
break;
case 3: /* FOUR BYTE SIGNED INTEGER */
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
#ifndef sparc
for(i = 0; i < array_size; i++)
{
cout<<r.four_int[i]<<endl;
int *temp = &r.four_int[i];
reverse(4,temp);
//print_stacktrace();
cout<<r.four_int[i]<<endl;
//r.four_int[i] = r.four_int[i] << 2 ;
}
#endif
h.rlen = (4 * array_size) + 4;
break;
case 5: /* EIGHT BYTE REAL */
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
#ifndef FPC
for (i = 0; i < array_size; i++) getr ((CONV *) (r.eight_real + i));
#endif
#ifdef FPC
for (i = 0; i < array_size; i++) fpc (r.eight_real + i);
#endif
h.rlen = (8 * array_size) + 4;
break;
case 6: /* CHARACTER ARRAY */
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
h.rlen = array_size + 4;
break;
default:
error.printf_exit("Error: bad record type %d in GdsBlock :: externaln", (int) h.data_type);
}
if (h.rlen % 2)
{
r.one_ascii[h.rlen] = 0;
h.rlen++;
}
cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl;
i = h.rlen - 4;
#ifndef sparc
c = (char *) &h.rlen;
tmp = c[0];
c[0] = c[1];
c[1] = tmp;
#endif
err = fwrite (&h, 1, sizeof (h), outstr);
if (err != sizeof(h))
{
err = ferror(outstr);
if (err)
{
char *s = strerror (err);
fclose (outstr);
error.printf_exit ("GdsBlock::write error - %s, errno %dn", s, err);
}
fclose (outstr);
error.printf_exit("Error: bad header fwrite in GdsBlock :: writen");
}
#if 1
err = fwrite (r.one_ascii, 1, i, outstr);
if (err != i)
{
err = ferror(outstr);
if (err)
{
char *s = strerror (err);
fclose (outstr);
error.printf_exit ("GdsBlock::write error - %s, errno %dn", s, err);
}
fclose (outstr);
error.printf_exit("Error: bad record fwrite in GdsBlock :: writen");
}
#endif
debug.printf("GdsBlock::write exitn");
TBX;
}
reverse()
根据平台反转字节顺序。这里显示的似乎只是reverse()
的非SPARC版本请参阅endianness。
在写入文件之前反转字节顺序(即调用reverse()
)的原因是为了使文件格式平台(即endianness)独立。
这是一些非常糟糕的代码。您在这里复制它时也犯了一些错误:您复制了GdsRecord
两次,并且GdsBlock::write
中的i
变量没有声明。
无论如何,这似乎应该做的是(我完全不确定它是否做了正确的事情,这取决于GdsRecord::len
是如何工作的,以及所有这些未充分记录的字段和幻数的确切含义是什么)以big-endian格式编写int
。
然而,它似乎没有用big-endian编写short
s,这很奇怪,因为我很确定这意味着它无论如何都不能在sparc/x86互操作性中工作。我不确定在double
s中使用什么endianness sparc,所以该部分可能工作,也可能不工作。此外,如果类型不是char
,我无法想出不部分写入数据的GdsBlock::write
读取方法。
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 64位机器上的C++内存对齐
- 使用不同的链接器会产生不同的机器代码吗
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 将项目从 Debian 8 Xenomai 2.x 迁移到 Debain 9 Xenomai 3.x
- 如何将经过训练的机器学习模型保存在python中并将其加载到C++中进行预测?
- C++ 两台不同机器之间通过wifi进行套接字通信
- 使用 ssh 重新连接到远程 Ubuntu 机器后,如何继续使用 gdb 调试 c++ 代码?
- 代码厨师 2019 年 12 月午餐时间愚蠢的机器
- CMake:尝试在 Jenkins 构建机器上运行时出现"Linked Library"错误 (0xc0000135)
- 从 MFC C++ 6.0 应用程序迁移到 VS 2005
- 将预处理器配置定义迁移到 constexpr,而不会造成内存膨胀
- objdump 不显示机器代码,但显示 ASM
- 如何在 MSVC C++中迁移 x64 的 x86 代码
- 不同机器之间的标准时钟性能差异显著
- "acceptor"在从TCP迁移到UDP时不是"boost::asio::ip::udp
- 将代码从 32 位迁移到 64 位时出现问题 Visual Studio 2010
- 将c++代码从32位机器迁移到64位机器