0
#include "stdio.h"

typedef struct CustomStruct
{
  short Element1[10];
}CustomStruct;

void F2(char* Y)
{
  *Y=0x00;
  Y++; 
  *Y=0x1F;    
}

void F1(CustomStruct* X)
{
  F2((char *)X);
  printf("s = %x\n", (*X).Element1[0]);
}

int main(void)
{
  CustomStruct s;
  F1(&s);

  return 0;
}

0x1f00上面的 C 代码在我的 PC 上编译和运行时会打印出来。

但是当我将它闪存到嵌入式目标(uController)并进行调试时,我发现 (*X).Element1[0] = 0x001f.

1-为什么PC和嵌入式目标上的结果不同?

2-我可以在此代码中修改什么以便它0x001f在 PC 机箱中打印,而不更改代码的核心(通过添加编译器选项或其他东西)。

4

3 回答 3

3

shorts 通常是两个字节和 16 位。当你说:

short s;
((char*)&s)[0] = 0x00;
((char*)&s)[1] = 0x1f;

这会将这两个字节中的第一个设置为 ,将这两个字节中0x00的第二个设置为0x1f。问题是 C++ 没有指定设置第一个或第二个字节对整体值的作用short,因此不同的平台可以做不同的事情。特别是,一些平台说设置第一个字节会影响short16 位的“最高有效”位,而设置第二个字节会影响 16 位的“最低有效”short位。其他平台则相反;设置第一个字节会影响最低有效位,而设置第二个字节会影响最高有效位。这两种平台行为分别称为大端和小端。


获得独立于这些差异的一致行为的解决方案是不访问short这种方式的字节。相反,您应该简单地操作语言确实short定义的using 方法的值,例如使用位和算术运算符。

short s;
s = (0x1f << 8) | (0x00 << 0); // set the most significant bits to 0x1f and the least significant bits to 0x00.

问题是,由于多种原因,我只能更改函数 F2 的主体。我不能改变它的原型。有没有办法在 Y 被城堡或其他东西之前找到它的大小?

您无法仅使用char*. 您必须通过其他方式知道正确的类型和尺寸。如果F2除了使用 CustomStruct 之外从未调用过,那么您可以简单地将其char*转换为CustomStruct这样的:

void F2(char* Y)
{
  CustomStruct *X = (CustomStruct*)Y;
  X->Element[0] = 0x1F00;
}

但请记住,这样的演员阵容通常是不安全的。您应该只将指针转换回它最初的来源。

于 2013-07-03T22:54:09.173 回答
2

可移植的方法是更改​​ 的定义F2

void F2(short * p)
{
    *p = 0x1F;
}

void F1(CustomStruct* X)
{
    F2(&X.Element1[0]);
    printf("s = %x\n", (*X).Element1[0]);
}

当您将对象重新解释为字符数组时,您会公开表示的实现细节,这本质上是不可移植的并且......依赖于实现。

如果您需要进行 I/O,即使用固定的、指定的外部线路格式进行接口,请使用和之类的函数htonsntohs转换并将平台细节留给您的库。

于 2013-07-03T22:49:47.023 回答
1

看起来 PC 是小端的,目标是大端的,或者有 16 位字符。

在 PC 上修改 C 代码没有很好的方法,除非您将char *引用替换为short *引用,并且可能使用宏来抽象微控制器和 PC 之间的差异。

例如,您可以创建一个宏PACK_BYTES(hi, lo),以相同的方式将两个字节打包成一个短字节,而不管机器字节序。您的示例变为:

#include "stdio.h"

#define PACK_BYTES(hi,lo) (((short)((hi) & 0xFF)) << 8 | (0xFF & (lo)))

typedef struct CustomStruct
{
  short Element1[10];
}CustomStruct;

void F2(short* Y)
{
    *Y = PACK_BYTES(0x00, 0x1F);
}

void F1(CustomStruct* X)
{
  F2(&(X->Element1[0]));
  printf("s = %x\n", (*X).Element1[0]);
}

int main(void)
{
  CustomStruct s;
  F1(&s);

  return 0;
}
于 2013-07-03T22:51:01.233 回答