具体来说,如果我创建一个具有单个字段的结构,它实际上充当该值的包装器,是否可以将此结构传递给期望基础类型的P/Invoke方法?
我正在使用一个本地库,其API涉及很多指针到结构类型,我想使用比IntPtr
更安全的类型来保存它们直接,通过将IntPtr
包装在通用结构中。那会有用吗? (它已经完成了吗?)
答案 0 :(得分:7)
只要您使用LayoutKind.Sequential
,结构的单个字段将位于偏移零处。因此,您的假设是正确的。
我认为通过指针到结构类型,你的意思是一个不透明的指针。结构是前向声明但从未定义。但是,在这种情况下,我无法看到如何在C#代码中声明一个结构可以真正帮助你。不透明的指针很不透明。只有库实现知道如何分配它。您无法在消费者中分配它。
<强>更新强>
也许你想在这样的结构中包装一个不透明的指针:
[StructLayout(LayoutKind.Sequential)]
struct FooHandle
{
IntPtr handle;
}
// and so on for other handle types
与此结构的互操作将与IntPtr
的互操作无法区分。
答案 1 :(得分:7)
不要将它作为结构传递给那么。
不要直接使用P / Invoke来确定如何直接执行此操作,而是保留P / Invoke方法private
,并公开将直接采用您的包装类型的公共方法 - 并处理您需要做的任何事情传递它。您的代码只会使用这些公共方法,而不必担心不安全的结构:)
混合使用不同类型并期望它们神奇地工作是一种灾难。让自己明确,不要依赖隐藏和隐式强迫演员。
关于这一点最好的事情是它允许你非常容易地使用一些实际上安全的指针包装器 - 你可以将它作为参考,如果它丢失了,你可以使用终结器根据需要处理非托管资源。看看SafeHandle
及其后代如何为一个很好的样本工作。