有一个单独的帮助程序程序集,其中仅包含旧 3rd 方组件的 P/Invoke 声明,如果程序集必须标记为符合 CLS,我想知道这两种方式中的哪一种是 The Better One™:
- 在
Int32
非托管声明具有unsigned int
. UInt32
在非托管声明具有的内部P/Invoke 声明中使用unsigned int
,并将其包装在一个公共方法中,该方法在调用内部方法时Int32
将其转换为。UInt32
这些的优点和缺点是什么?
有一个单独的帮助程序程序集,其中仅包含旧 3rd 方组件的 P/Invoke 声明,如果程序集必须标记为符合 CLS,我想知道这两种方式中的哪一种是 The Better One™:
Int32
非托管声明具有unsigned int
.UInt32
在非托管声明具有的内部P/Invoke 声明中使用unsigned int
,并将其包装在一个公共方法中,该方法在调用内部方法时Int32
将其转换为。UInt32
这些的优点和缺点是什么?
如果您使用选项 1,我认为您不会得到正确的行为。 Int32 只能达到 2,147,483,647。而 unsigned int 则高达 4,294,967,295。只要你知道你不需要任何超过 20 亿的值,这并不重要。但为了技术上正确,公共接口应该公开一个更大的类型并执行边界检查以确保它适合 unsigned int,如果不适合则抛出异常。一个 Int64 就可以了 (9,223,372,036,854,775,807)。
当 uint 变得太大时,P/Invoke 编组器不会抱怨,你只会得到一个负整数。额外的层确实允许您使用选中的关键字来生成溢出异常。这是相当可取的。
是否值得麻烦是次要问题。许多 API,如 Win32,使用无符号作为逻辑约束。就像字符串的长度或内存块的大小一样,它永远不会是负数。在实践中,这样的数字永远不会溢出。因为不可能分配那么多内存。我不记得曾经在应该使用 uint 的 API 中运行过一次。因此,我认为您只需使用带有整数的直接 pinvoke 声明就可以了。