结构是否会增加实例大小的开销?

Mas*_*ler 9 .net c# pinvoke

具体来说,如果我创建一个具有单个字段的结构,它实际上充当该值的包装器,将此结构传递给期望底层类型的P/Invoke方法是否安全?

我正在使用一个本地库,其API涉及许多指针到结构类型,并且我想IntPtr通过包装IntPtr在通用结构中来使用比使它们更直接的类型更安全的东西.那会有用吗?(它已经完成了吗?)

Dav*_*nan 7

只要你使用LayoutKind.Sequential,那么struct的单个字段将位于零偏移处.因此,您的假设是正确的.

我假设通过指针到结构类型,你的意思是一个不透明的指针.结构是前向声明但从未定义.但是,在这种情况下,我无法看到如何在C#代码中声明一个结构可以真正帮助你.不透明的指针很不透明.只有库实现知道如何分配它.您无法在消费者中分配它.

更新

也许你想在这样的结构中包装一个不透明的指针:

[StructLayout(LayoutKind.Sequential)]
struct FooHandle
{
    IntPtr handle;
}

// and so on for other handle types
Run Code Online (Sandbox Code Playgroud)

与此结构的互操作将与互操作无法区分IntPtr.


Lua*_*aan 7

那么,不要将它作为结构传递.

不要直接使用P/Invoke来确定如何直接执行此操作,只需保留P/Invoke方法private,并公开将直接采用您的包装类型的公共方法 - 并处理您需要做的任何事情以将其传递.您的代码只会使用这些公共方法而不必担心不安全的结构:)

混合不同类型并期望它们神奇地工作是一种灾难.让自己明确,不要依赖隐藏和隐式强制转换.

关于这一点最好的事情是它允许你非常容易地使用一些实际上安全的指针包装器- 你可以将它作为参考,如果它丢失了,你可以根据需要使用终结器来处理非托管资源.看看如何SafeHandle以及它的后代如何为一个伟大的样本工作.