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

时间:2016-02-09 12:03:58

标签: c# c++ marshalling wrapper

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

使用包含托管和本机部分(C ++和C#)以及普通C样式接口(PinvokesMarshal ..)的应用程序时,这种数据类型大小的不一致可能会导致很多混乱。

那么,在界面中使用始终固定大小的数据类型是否合适?它有任何缺点吗?

3 个答案:

答案 0 :(得分:2)

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

在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格式存储floatdouble采用64位IEEE-754格式。

我不知道.NET是否定义了修复格式,但根据我的经验,.NET和Mono以相同的方式执行(float = System.Single是32位IEEE-754和{ {1}} = double是64位IEEE-754。

所以你可以决定你是否相信我对C ++方面的观察......

答案 1 :(得分:0)

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

此外,还不清楚64位整数对你有好处还是坏处。这取决于你在做什么。他们会占用更多空间,这是肯定的。

答案 2 :(得分:0)

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

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

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