繁体   English   中英

正确的方法来组织SIZE_T *?

[英]Correct way to marshal SIZE_T*?

我有以下C ++函数定义,我试图通过托管代码通过PInvoke调用:

bool FooBar(SIZE_T* arg1);

我的管理声明如下:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref uint arg1);

有些人可能会注意到我最终做的同样的错误。 这不是64位便携式。 SIZE_T的大小可变(32-64位),指针也是如此。 在托管大小上,指针正确转换为64位,但uint没有,并且您最终可以在arg1的高位中使用垃圾。 这是一个特别持久的错误,因为垃圾通常只是零:(

我已经开始工作的唯一解决方案是以下管理声明:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref IntPtr arg1);

这当然有效,因为IntPtr可以正确地改变它的大小。 在我的代码中,我只是将IntPtr视为一个整数,它可以工作,虽然它看起来像一个丑陋的黑客。 在我看来应该有一些方法来正确指定,也许使用UnmanagedType.SysUInt,但我无法提出任何其他工作解决方案。

使用IntPtr和/或UIntPtr 适当做-的类型有专门用于此目的! 我不明白为什么你认为这是一个“丑陋的黑客”。 我也不确定你提议的替代方案是什么 - 允许将值映射到uint任何类型的属性本质上都是错误的,因为无论架构如何,C# uint都保证是32位的,所以64-位平台,要正确编组它,它必须修剪一半,丢失数据,并可能使结果无用。

UIntPtr是要使用的正确类型。

size_t是一个无符号的,指针大小的整数,这正是UIntPtr的含义。 我同意,名字中的“ptr”可能有点令人困惑。 它实际上并不意味着“这是一个指针”,它意味着“这是一个指针大小的整数”。 所以你的声明是:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref UIntPtr arg1);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM