C# 复杂c结构到ref类-无法封送

C# 复杂c结构到ref类-无法封送,c#,marshalling,unmanaged,managed,mixed-mode,C#,Marshalling,Unmanaged,Managed,Mixed Mode,我在将我的c结构编组到一个ref类上已经有一段时间了 我需要跨越非托管c数据到c的边界,所以我用c代码和一些ref类构建了一个混合模式dll。我在填充c结构的混合模式dll中调用了一些c函数。此外,我还编写了一个wrapper ref类,以使tha数据可用于我的c#项目。 现在,我需要将非托管数据“转换”到托管的re类。由于(对我来说)未知的原因,这失败了 以下是C++/CLI代码: mymanaged cli_struct; myunmanaged c_Struct; bool res

我在将我的c结构编组到一个ref类上已经有一段时间了

我需要跨越非托管c数据到c的边界,所以我用c代码和一些ref类构建了一个混合模式dll。我在填充c结构的混合模式dll中调用了一些c函数。此外,我还编写了一个wrapper ref类,以使tha数据可用于我的c#项目。 现在,我需要将非托管数据“转换”到托管的re类。由于(对我来说)未知的原因,这失败了

以下是C++/CLI代码:

mymanaged   cli_struct;
myunmanaged c_Struct;

bool res = fillupstruct(&c_struct);
if(res)
{
   // copy unmanaged structure to managed 
   System::IntPtr ptr = System::IntPtr(&c_struct);
   cli_struct = (mymanaged^)Marshal::PtrToStructure(ptr, mymanaged->GetType());   // <----- this call fails ...
}
我已经写下了这些值,并将它们转移到托管结构中

注意:“内联数组”借用自: Mark Hall编写的内联数组模板,Shaun对其进行了改进 米勒:

还有一件事是我不知道如何处理这两个位域变量

我现在有点不知道问题出在哪里。有人能帮我吗

顺便说一句:我也尝试过,但运气不好(C++/CLI):


我不直接将函数和结构Pinvoke到C#的原因是,C代码中有更复杂的东西,我想完全隐藏在我的C#代码中。

在C++/CLI中这样做没有任何好处,可以直接在C#中这样做,因为
PtrToStructure
复制数据。此外,
ref类
不是一个结构,您必须使用
value结构
,但您将无法引用数组或任何与此相关的引用(使用
^
的任何内容)。在C++/CLI中这样做没有任何好处,您可以直接在C中这样做,as
PtrToStructure
复制数据。此外,
ref类
不是一个结构,您必须使用
值结构
,但您将无法引用数组或任何作为该问题引用的内容(任何带有
^
的内容)。
   [StructLayoutAttribute(LayoutKind::Explicit)] ///, Pack=2)]
   public ref class mymanaged   
   {
   public:
      [FieldOffset(0)]
      Versions m_Ver;
      [FieldOffset(8)]
      State m_State;
      [FieldOffset(72)]
      Info m_MoDta;
      [FieldOffset(136)]
      Parameters m_Param;
      [FieldOffset(264)]
      Settings m_Set;
      [FieldOffset(312)]
      [MarshalAs(UnmanagedType::ByValArray, SizeConst = 3)]
      array<T_RmD^>^ m_MSys; // -->  "T_RmD  m_MSys[3];" in c-struct
      [FieldOffset(440)]
      PARAM m__Params;

      private:
      void InitializeInstanceFields()
      {
         m_MSys = gcnew array<T_RmD^>(3);
      }

      public:
      ToolData()
      {
         InitializeInstanceFields();
      }
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct Versions
   {
      [FieldOffset(0)]
      UInt16 m_hw_majorVersion; 
      [FieldOffset(sizeof(UInt16))]
      UInt16 m_hw_minorVersion; 
      [FieldOffset(2*sizeof(UInt16))]
      UInt16 m_majorVersion; 
      [FieldOffset(3*sizeof(UInt16))]
      UInt16 m_minorVersion; 
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct State
   {
      [FieldOffset(0)]
      UInt16 STATUS; 
      [FieldOffset(2)]
      UInt16 KOMMAND; 
      [FieldOffset(4)]
      UInt16 ERR; 
      [FieldOffset(6)]
      UInt16 WAR;
      [FieldOffset(8)]
      UInt16 TEM_1;
      [FieldOffset(10)]
      UInt16 TEM_2;
      [FieldOffset(12)]
      UInt16 TEM_3;
      [FieldOffset(14)]
      UInt16 TEM_4;
      [FieldOffset(16)]
      [MarshalAs(UnmanagedType::LPArray, SizeConst = 4)]
      inline_array <UInt32,4> res; --> simply a uint16 [4] in c-struct
      [FieldOffset(32)]
      UInt16 cccc;
      [FieldOffset(34)]
      UInt16 AW;
      [FieldOffset(36)]
      UInt16 PMs_1;
      [FieldOffset(38)]
      UInt16 PMs_2;
      [FieldOffset(40)]
      UInt16 PKo;
      [FieldOffset(42)]
      UInt16 Tp;
      [FieldOffset(44)]
      UInt16 Aga;
      [FieldOffset(46)]
      UInt16 Alog_1; 
      [FieldOffset(48)]
      UInt16 Alog_2;
      [FieldOffset(50)]
      UInt16 Alog_3;
      [FieldOffset(52)]
      UInt16 Alog_4;
      [FieldOffset(54)]
      UInt16 Alog_5;
      [FieldOffset(56)]
      UInt16 Alog_6;
      [FieldOffset(58)]
      UInt16 ResPtr;
      [FieldOffset(60)]
      UInt16 AddBelKen;
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct Info
   {
      [FieldOffset(0)]
      UInt16 RotNU;
      [FieldOffset(2)]
      UInt16 MotR;
      [FieldOffset(4)]
      UInt16 MotH;
      [FieldOffset(6)]
      UInt16 Momkon;
      [FieldOffset(8)]
      UInt16 amp_a;
      [FieldOffset(10)]
      UInt16 LeerA;
      [FieldOffset(12)]
      UInt16 LeerB;
      [FieldOffset(14)]
      UInt16 FP;
      [FieldOffset(16)]
      UInt16 MinD;
      [FieldOffset(18)]
      UInt16 MotP;
      [FieldOffset(20)]
      Int16  MomSh;

// TODO Bitfield offset ???? --> these are bitfields in c-code
// i have no clue what to do with these...
      [FieldOffset(??)]
      UInt16 I2Gr;          // c-code:  unsigned short  I2Gr:8;
      [FieldOffset(??)]
      UInt16 I2TK;          // c-code:  unsigned short  I2TK:8;

      [FieldOffset(24)]
      UInt16 GetUes;
      [FieldOffset(26)]
      UInt16 MinMoS; 
      [FieldOffset(28)]
      UInt16 SGr;
      [FieldOffset(30)]
      UInt16 AbD;
      [FieldOffset(32)]
      UInt16 MomKf;
      [FieldOffset(34)]
      UInt16 m_HaUG;
      [FieldOffset(36)]
      UInt16 m_HaOG;
      [FieldOffset(38)]
      [MarshalAs(UnmanagedType::LPArray, SizeConst = 12)]
      inline_array<UInt16,12> Reserviert;    ///< Reserve --> simply a uint16 [12] in c-struct
      [FieldOffset(62)]
      UInt16 _Cr;
   };

   [System::Runtime::CompilerServices::UnsafeValueType]
   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct Parameters
   {
      [FieldOffset(0)]
      UInt16 m_EM;             
      [FieldOffset(2)]
      UInt16 m_PUPm;              
      [FieldOffset(4)]
      UInt16 m_ALW;         
      [FieldOffset(6)]
      UInt16 m_RMno;  
      [FieldOffset(8)]
      [MarshalAs(UnmanagedType::ByValTStr, SizeConst = 16)]
      inline_array<Char,16> m_WST;
      [FieldOffset(24)]
      UInt32 m_S;              
      [FieldOffset(28)]
      UInt16 m_ST;           
      [FieldOffset(30)]
      UInt16 m_Res;                
      [FieldOffset(32)]
      UInt16 m_mmnar;              
      [FieldOffset(34)]
      UInt16 m_mmxar;              
      [FieldOffset(36)]
      UInt16 m_dar;              
      [FieldOffset(38)]
      UInt16 m_AMaR;       
      [FieldOffset(40)]
      UInt16 m_AMh;        
      [FieldOffset(42)]
      UInt16 m_APh;      
      [FieldOffset(44)]
      UInt16 m_So;              
      [FieldOffset(46)]
      UInt16 m_WDn;         
      [FieldOffset(48)]
      UInt16 m_WDx;         
      [FieldOffset(50)]
      UInt16 m_WMN;                   
      [FieldOffset(52)]
      UInt16 m_WMX;                   
      [FieldOffset(54)]
      UInt16 m_WMS;             
      [FieldOffset(56)]
      UInt16 m_WBw;    
      [FieldOffset(58)]
      UInt16 m_WSw; 
      [FieldOffset(60)]
      UInt16 m_WKn;                
      [FieldOffset(62)]
      UInt16 m_WKx                
      [FieldOffset(64)]
      [MarshalAs(UnmanagedType::ByValArray, SizeConst = 31)]
      inline_array<UInt16,31> Reserviert; 
      [FieldOffset(126)]
      UInt16 m_C;                       
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct og_spec
   {
      [FieldOffset(0)]
      UInt16 m_av;
      [FieldOffset(2)]
      Int16 m_dr;
      [FieldOffset(4)]
      UInt32 m_ef;
      [FieldOffset(8)]
      float m_val;
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct Settings
   {
      [FieldOffset(0)]
      UInt16 m_MoKW;
      [FieldOffset(2)]
      UInt16 m_reserved;
      [FieldOffset(4)]
      UInt16 m_StO;
      [FieldOffset(6)]
      UInt16 m_res1;
      [FieldOffset(8)]
      UInt16 m_res2;
      [FieldOffset(10)]
      UInt16 m_Me1Kw;
      [FieldOffset(12)]
      UInt16 m_Me2Kw;
      [FieldOffset(16)]
      og_spec m_og;
      [FieldOffset(28)]
      UInt16 m_C;
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct PARAM
   {
      [FieldOffset(0)]
      Int16 TE_AOs;
      [FieldOffset(2)]
      UInt16 TE_AF;
      [FieldOffset(4)]
      UInt16 AOf; 
      [FieldOffset(6)]
      UInt16 AFa; 
      [FieldOffset(8)]
      UInt32 TBc;
   };

   [StructLayoutAttribute(LayoutKind::Auto)]
   public value class TSFlags
   {
   public:
      bool TSgn;
      UInt32 all;
   };

   [StructLayoutAttribute(LayoutKind::Explicit)]
   public value struct _parts
   {
   public:
      [FieldOffset(0)]
      UInt32 Cal;
      [FieldOffset(4)]
      UInt32 Of;
      [FieldOffset(8)]
      UInt32 SN;
      [FieldOffset(12)]
      UInt32 SWV;
      [FieldOffset(16)]
      UInt32 Rge;
      [FieldOffset(20)]
      UInt32 Anre;
      [FieldOffset(24)]
      TSFlags Fl;
   };

   [StructLayoutAttribute(LayoutKind::Auto)]
   public value struct T_RmD
   {
   public:
      _parts ^parts;
      [MarshalAs(UnmanagedType::LPArray, SizeConst = 2)]
      inline_array<UInt32,2> RmD;
   };
printf("Offset Of %s: \t\t%lu\n", VNAME(m_Versions), FIELD_OFFSET(DataType, m_Ver));
// here fro reference from some windows headers:
#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))
#define VNAME(x) #x
GCHandle handle = GCHandle::Alloc(tdata, GCHandleType::Pinned);
try
{
   IntPtr pointer = handle.AddrOfPinnedObject();

  fillupstruct((DataType*)(void*)pointer);
}
finally
{
   if (handle.IsAllocated)
   {
      handle.Free();
   }
}