C# 复杂c结构到ref类-无法封送
我在将我的c结构编组到一个ref类上已经有一段时间了 我需要跨越非托管c数据到c的边界,所以我用c代码和一些ref类构建了一个混合模式dll。我在填充c结构的混合模式dll中调用了一些c函数。此外,我还编写了一个wrapper ref类,以使tha数据可用于我的c#项目。 现在,我需要将非托管数据“转换”到托管的re类。由于(对我来说)未知的原因,这失败了 以下是C++/CLI代码: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
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中这样做,asPtrToStructure
复制数据。此外,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();
}
}