【问题标题】:C changing the value of the pragma pack variable based on bitnessC 根据位数更改 pragma pack 变量的值
【发布时间】:2018-04-09 03:16:43
【问题描述】:

我有一个可以通过 Python、Excel 和 C# 访问的 c 库。为了使用 vba 类型,我需要使用 pragma pack 指令来获得某种正确的结构对齐。

我对使用 c 指令不是很熟悉,但我知道要在 excel(我的计算机上是 32 位)中使用它,我需要用 pragma pack( 4) 像这样

#pragma pack(4)

typedef struct
{
    double myDouble;
    int myInt;
} Mystruct;

....

#pragma pack()

在接收端(例如 VBA)我现在可以这样做

Type MyVBAStruct
    myDouble as Double
    myInt as Long
End Type

对于 C#,我定义了我的结构

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
public struct myCSharpStruct
{ 
    public double myDouble;
    public int myInt;
}

这一切都很好。

但是,在某些情况下,我还必须构建 64 位,在这种情况下,我有 使用pragma pack(8) .... pragma pack()。目前我必须手动进行切换。这当然不是一个很好的解决方案。理想情况下,我希望能够写

#pragma pack(PACK_SIZE)

typedef struct
{
    double myDouble;
    int myInt;
} Mystruct;

....

#pragma pack()

PACK_SIZE 是一个宏,它以某种方式自动检测构建的位数。

理想情况下,C# 会发生类似的事情(类型包含在同一个解决方案中)。

有没有办法做到这一点?

【问题讨论】:

  • 你的编译器,你没有提到,可能有预处理器定义,你可以用它来确定你是编译 32 位还是 64 位。假设您使用的是 Visual Studio,这可能会有所帮助:stackoverflow.com/questions/8672887/…
  • 是的,我正在使用 Visual Studio。感谢您的提示,我会检查一下。我不确定编译器。我猜它是默认编译器。不记得它的名字了。
  • 看起来很有希望顺便说一句...我在您回答时编辑了我的问题。你知道如何在 C# 中做同样的事情吗?
  • stackoverflow.com/questions/266082/… 由于 C# 并未针对任何特定架构进行严格编译,因此您只能在运行时判断。我不知道该信息是否可用于您的特定情况。

标签: c pragma


【解决方案1】:

您可能没有意识到这一点,但您实际上要做的不是修复对齐,而可能只是为了摆脱 struct padding。

因为结构的正确对齐已经由 C 编译器自动处理。当您在 64 位 PC 上运行它时,您可能会得到 16。为什么这对 VBA 等不好,我不知道,但我会假设它不喜欢填充,因为#pragma pack(4) 会给你12 而不是16

因此,无论 int 的大小如何,您都可以通过去掉所有填充来解决问题。这是通过 #pragma pack(1) 完成的,无论是 32 位还是 64 位都可以。

请注意,#pragma pack 不是标准 C,在不同的编译器上可能表现不同。

【讨论】:

  • 是的。填充是正确的术语。我真的很想保留使用pragma pack(4) 的选项,因为这样我就可以使用VBA。这是我能够调用 VBA 的唯一方法(相信我,我尝试过其他方法:|)。
猜你喜欢
  • 2018-10-30
  • 2015-09-17
  • 1970-01-01
  • 2011-10-29
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2016-06-04
相关资源
最近更新 更多