C# 中的 C++ int & long 编组
Posted
技术标签:
【中文标题】C# 中的 C++ int & long 编组【英文标题】:C++ int & long marshalling in C# 【发布时间】:2010-12-27 20:02:16 【问题描述】:我目前正在将专有 dll(一种 API)移植到 C#,在编组一些使用的数据类型时遇到了一些问题。
例如API头文件定义了以下类型:
typedef unsigned int tINT; /* natural unsigned */
typedef signed int tINTs; /* natural signed */
typedef unsigned int tLONG; /* 32 bit unsigned */
typedef unsigned long tPTR; /* 32/64-bit pointer */
然后我例如有以下函数定义:
tINTs SomeApiFunction ( const tPTR hdl, tINT param );
我通常将int
直接与C# 的int
(Int32
) 或未签名版本进行编组。 API 的tLONG
和tINT
是一样的(至少对于API)。但我不确定tPTR
。我现在在 C# 中将其设为 uint
,因为它是 32 位 int,但我不确定 long
在 64 位机器上的表现如何。
我必须做些什么来确保 API 可以在 32 位和 64 位机器上正常工作?
这就是我现在要做的:
[DllImport( "api.dll" )]
public static extern int SomeApiFunction ( uint hdl, uint param );
遗憾的是,API 并没有很好的记录,因此我不确定所有这些(重叠的)typedef 的意图是什么。除了我上面包含的标题 cmets 之外,没有关于实际类型的信息。
【问题讨论】:
【参考方案1】:尝试将其编组为IntPtr
。 IntPtr 在 .Net 中在 32 位系统上为 4 个字节,在 64 位系统上为 8 个字节。
【讨论】:
哦,只是一个快速的附加问题:我应该使用IntPtr
还是UIntPtr
,因为那里的指针是 unsigned 长的?
除非你因为指针算法而在处理负值时遇到问题,否则你仍然应该使用 IntPtr。来自 msdn 文档: IntPtr 类型符合 CLS,而 UIntPtr 类型不符合。在公共语言运行库中仅使用 IntPtr 类型。提供 UIntPtr 类型主要是为了与 IntPtr 类型保持架构对称性。【参考方案2】:
它是 C/C++ 编译器的实现细节。您应该通过注释并声明它为 IntPtr。如果代码是由 MSVC 编译器编译的,那么它将无法在 64 位模式下工作,它会长期使用 32 位。不足以存储指针。
【讨论】:
你的意思是什么,它不能在 64 位上工作?我的示例 C# 代码,或整个 API(不会让我感到惊讶。)? 整个 API 以及您的 C# 示例。您是否有该 DLL 的预构建 64 位版本?您通常可以四处逛逛并了解它是如何构建的。 不,我只有一个 DLL.. :/ 好吧,那就别担心了。您必须将 C# 项目的目标平台设置为 x86。使用 IntPtr,也许他们有一天会修复它。 啊,好的,我稍后会尝试联系供应商;现在它只适用于 x86 就足够了。非常感谢:)【参考方案3】:这里是good list of type correspondence.
对于指针类型,在 C# 中通常为 IntPtr
。
【讨论】:
【参考方案4】:如果我没记错的话 int
uint
和其他原始类型是底层 Windows API 的正确类型。
但是,对于指针,最好在 C# 端使用 IntPtr
,在 C/C++ 端使用 void*
。
【讨论】:
以上是关于C# 中的 C++ int & long 编组的主要内容,如果未能解决你的问题,请参考以下文章