我应该在与 C# 交互时使用固定大小的数据类型吗

Should I use fixed size data types while interfacing with C#

据我所知,C++ 标准不保证 int 等基本数据类型的大小。它只是保证表示 int 变量的最少位数。因此,从平台到平台,这可能会发生变化。

在使用包含托管部分和本机部分(C++ 和 C#)的应用程序以及普通 C 风格界面(PinvokesMarshal..)时,这种不一致的数据类型大小可能会导致乱七八糟。

那么,在界面中始终使用固定大小的数据类型好吗?它有什么缺点吗?

由于 C# int 始终是 32 位的,您必须确保您的 C++ 部分在连接时也使用 32 位整数。缺点不应该让你担心,因为这是必须的。

另外,不清楚 64 位整数对您来说是好是坏。这取决于你在做什么。他们会拿走更多 space,那是肯定的。

您可以定义自己的数据类型,无论您使用何种架构,其大小都不会改变。优点是当你移动到不同的架构(例如 32 到 64 位等)时,你不需要修改你的程序。缺点是,假设您最初是为 32 位编写程序并考虑以下内容,并且您已经定义了这样的 64 位数据类型。

typedef struct A
{
  int a;
  int b;
} my64bitint;

要使用它,您需要编写自己的代码。当你移动到 64 位时,你可以继续使用相同的,但是你将无法获得你在新 arch 中获得的 64 位整数的优势。您需要更改代码以使用 64 位整数。

对于整数类型:是的,你应该。

在 C# 端更容易,因为所有整数类型都有固定大小,不依赖于平台位数。

在 C++ 端,您可以使用以下相应类型:

int8_t -> sbyte = System.SByte,这不是 ECMA 标准,但在 :NET 和 Mono

中可用

uint8_t->byte=System.Byte

int16_t -> short = System.Int16

uint16_t->ushort=System.UInt16

int32_t -> int = System.Int32

uint32_t->uint=System.UInt32

int64_t -> long = System.Int64

uint64_t->ulong=System.UInt64

交换指针类型也是安全的。尽管它们的大小可能会有所不同,但对于特定进程的调用方和被调用方大小始终相同。

即:如果进程是 64 位的,则您的 C++ 代码必须已编译为 64 位,因此它的指针具有 64 位。此过程将使用 64 位 .NET 运行时,因此 .NET 中的指针也将是 64 位。

(顺便说一句:C# 中的指针类型是 System.IntPtr... *)。

对于浮点类型来说有点难。 C++ 标准没有给你任何提示 floatdouble 是如何存储的。不是尺寸也不是技术。 实际上,我所知道的所有 C/C++ 编译器(MSVC、gcc/g++、clang/clang++)在我使用过的所有平台上(Windows、MinGW、 Linux) 以 32 位 IEEE-754 格式存储 float,以 64 位 IEEE-754 格式存储 double

我不知道 .NET 是否定义了固定格式,但根据我的经验,.NET 和 Mono 以相同的方式进行(float= System.Single 是 32 位 IEEE-754 和 double= System.Double 是 64 位 IEEE-754).

因此您可以决定是否相信我对 C++ 方面的观察...