将包含枚举的C++结构封送至C#

Marshalling C++ Struct Containing Enums to C#

本文关键字:结构 C++ 包含 枚举      更新时间:2023-10-16

下面的C++结构需要编组到C#。它将来自Tablet触摸传感器的输入表示为wm_Tablet_flick消息。因此,我尝试在C#应用程序中处理这些消息:

    typedef struct FLICK_DATA {
      FLICKACTION_COMMANDCODE iFlickActionCommandCode  :5;
      FLICKDIRECTION          iFlickDirection  :3;
      BOOL                    fControlModifier  :1;
      BOOL                    fMenuModifier  :1;
      BOOL                    fAltGRModifier  :1;
      BOOL                    fWinModifier  :1;
      BOOL                    fShiftModifier  :1;
      INT                     iReserved  :2;
      BOOL                    fOnInkingSurface  :1;
      INT                     iActionArgument  :16;
    } FLICK_DATA;

其中:

    typedef enum FLICKACTION_COMMANDCODE {
      FLICKACTION_COMMANDCODE_NULL          = 0,
      FLICKACTION_COMMANDCODE_SCROLL        = 1,
      FLICKACTION_COMMANDCODE_APPCOMMAND    = 2,
      FLICKACTION_COMMANDCODE_CUSTOMKEY     = 3,
      FLICKACTION_COMMANDCODE_KEYMODIFIER   = 4 
    } FLICKACTION_COMMANDCODE;

和:

typedef enum FLICKDIRECTION {
  FLICKDIRECTION_RIGHT       = 0,
  FLICKDIRECTION_UPRIGHT     = 1,
  FLICKDIRECTION_UP          = 2,
  FLICKDIRECTION_UPLEFT      = 3,
  FLICKDIRECTION_LEFT        = 4,
  FLICKDIRECTION_DOWNLEFT    = 5,
  FLICKDIRECTION_DOWN        = 6,
  FLICKDIRECTION_DOWNRIGHT   = 7,
  FLICKDIRECTION_INVALID     = 8 
} FLICKDIRECTION;

在C#方面,我得到:

    [StructLayout(LayoutKind.Sequential)]
    private struct FLICKDATA
    {
        internal FLICKACTION_COMMANDCODE iFlickActionCommandCode;
        internal FLICKDIRECTION iFlickDirection;
        public bool fControlModifier;
        public bool fMenuModifier;
        public bool fAltGRModifier;
        public bool fWinModifier;
        public bool fShiftModifier;
        public int iReserved;
        public bool fOnInkingSurface;
        public int iActionArgument;
    }
    public enum FLICKDIRECTION
    {
      FLICKDIRECTION_RIGHT       = 0,
      FLICKDIRECTION_UPRIGHT     = 1,
      FLICKDIRECTION_UP          = 2,
      FLICKDIRECTION_UPLEFT      = 3,
      FLICKDIRECTION_LEFT        = 4,
      FLICKDIRECTION_DOWNLEFT    = 5,
      FLICKDIRECTION_DOWN        = 6,
      FLICKDIRECTION_DOWNRIGHT   = 7,
      FLICKDIRECTION_INVALID     = 8 
    }
    public enum FLICKACTION_COMMANDCODE
    {
      FLICKACTION_COMMANDCODE_NULL          = 0,
      FLICKACTION_COMMANDCODE_SCROLL        = 1,
      FLICKACTION_COMMANDCODE_APPCOMMAND    = 2,
      FLICKACTION_COMMANDCODE_CUSTOMKEY     = 3,
      FLICKACTION_COMMANDCODE_KEYMODIFIER   = 4 
    }

然后我确定结构的大小如下:

private int _flickDataSize = Marshal.SizeOf(new FLICKDATA());

最后尝试使用将指针转换为结构

     FLICKDATA data = new FLICKDATA();
     data = (FLICKDATA)Marshal.PtrToStructure(m.WParam, typeof(FLICKDATA));

或者使用内置的GetLParam方法:

     data = (FLICKDATA)m.GetLParam(typeof(FLICKDATA));

但这两种解决方案都不起作用,要么是空的,要么是垃圾。我在这里做错了什么?

您尝试过转换数据吗?而不是直接尝试那样访问它?或者创建一个指向FlickData的指针。也没有数据是随机的!/垃圾在那里是有原因的,你只需要理解为什么会在那里。

所以,是的,试着创建一个指向FlickData或:的指针

FLICKDATA*数据=FLICKDATA;试试看(也许必须玩一玩)

尝试将Flickdata转换到您的数据变量中:自动数据(static_cast(FLICKDirection);