C# 如何隐式地转换这个?
我正在尝试围绕一些本机DLL结构创建一些包装器类。以下是我得到的:C# 如何隐式地转换这个?,c#,design-patterns,interop,C#,Design Patterns,Interop,我正在尝试围绕一些本机DLL结构创建一些包装器类。以下是我得到的: public class Event // <-- managed class { internal SDL_Event _event; public EventType Type { get { return (EventType) _event.type; } } public KeyboardEvent Key { get
public class Event // <-- managed class
{
internal SDL_Event _event;
public EventType Type
{
get { return (EventType) _event.type; }
}
public KeyboardEvent Key
{
get
{
return new KeyboardEvent(_event.key); // <-- I want to avoid making a copy of the struct here
}
}
}
[StructLayout(LayoutKind.Explicit)]
internal unsafe struct SDL_Event // <-- a union holding ~15 different event types
{
[FieldOffset(0)] public UInt32 type;
[FieldOffset(0)] public SDL_KeyboardEvent key;
[FieldOffset(0)] private fixed byte _padding[56];
}
public class KeyboardEvent
{
private SDL_KeyboardEvent _event;
internal KeyboardEvent(SDL_KeyboardEvent e)
{
_event = e;
}
// some properties that deal specifically with SDL_KeyboardEvent
}
[StructLayout(LayoutKind.Sequential)]
internal struct SDL_KeyboardEvent
{
public UInt32 type; // <-- sits in the same memory location as SDL_Event.type
public UInt32 timestamp;
public UInt32 windowID;
public byte state;
public byte repeat;
private byte _padding2;
private byte _padding3;
public SDL_Keysym keysym;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SDL_Keysym
{
public UInt32 scancode;
public Int32 sym;
public UInt16 mod;
private UInt32 _unused;
}
公共类事件//
这是我对结构所能做的最好的了。对于类,您必须以通常的方式编写一些显式强制转换,但这应该会有所帮助。既然两个结构都有相同的数据,为什么要创建两个结构?让类使用继承,并使用parent@MEYWD:它们的数据并不完全相同。数据只共享相同的内存空间;一些成员变量可能相同,但它们并不都相同。能否使用显式布局,并将NativeEvent
和NativeKeyboardEvent
放入联合结构中@罗伯塔维:是的。这有点混乱,但我现在就是这么做的。为什么不在链接中使用不安全的方式呢?关于显式强制转换,C#不允许您显式地从基类强制转换到派生类。此外,此方法完成强制转换,但如果我没有弄错的话,仍然将整个56字节的结构复制到一个out-of-this方法中。它们是structs。你期待什么?如果你想要这种技巧,你需要直接复制成员。我在你的原始代码中没有看到任何继承。是的。。它们是结构,因为它们在C中就是这样定义的。这就是为什么我将它们包装在类中,这样我的API用户就不必处理这些废话了。我尽量不引入任何额外的开销,那么您可能会更幸运地编写真正的类,这些类接受构造函数中的原始结构进行水合作用。如果愿意,您甚至可以重载构造函数,以便它们可以接受任何一种结构。
unsafe static SDL_KeyboardEvent ToSDL_KeyboardEvent (SDL_Event event)
{
return *((SDL_KeyboardEvent*) &event);
}