If you really想要与本机代码互操作,可以使用fixed
操作员:
var array = new tagTimeHistory[dataCounts.m_nNumTH];
fixed (tagTimeHistory* ptr = array)
{
// do anything with the raw pointer
}
注意fixed
C# 中的运算符和指针类型需要unsafe
能力。你可能想更换IntPtr
具有适当的指针类型以提高类型安全性(尽管有一种方法可以将指针转换为IntPtr
s 并返回)。
执行相同操作的另一种方法是通过以下方法Marshal class http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.110).aspx.
EDIT.这是修订后的示例unsafe你有趣的命名联合结构的定义:
[StructLayout(LayoutKind.Explicit)]
public unsafe struct Anonymous_d2bf9406_c664_4664_9196_800cc23f445a
{
[FieldOffset(0)]
public stTimeHistory_t* m_ThRecs;
[FieldOffset(0)]
public stInterval_t* m_Interval;
[FieldOffset(0)]
public stExceedence_t* m_Exceedences;
[FieldOffset(0)]
public stRunRecord_t* m_RunRecord;
[FieldOffset(0)]
public stSpeechData_t* m_VoiceRecord;
[FieldOffset(0)]
public stSpeechData_t* m_AudioRecord;
}
您应该定义所有结构,例如stTimeHistory_t
在你的代码中(或者用通用的替换你不关心的代码)IntPtr
s).
关于结构数组的创建Marshal
:本机内存池没有这样的概念structure array
;它只关心字节。例如,您可以使用Marshal.AllocHGlobal method http://msdn.microsoft.com/en-us/library/s69bkh17(v=vs.110).aspx:
IntPtr myPtr = Marshal.AllocHGlobal(Marshal.SizeOf<tagTimeHistory>() * dataCounts.m_nNumTH);
// ... write something to an array, use it
// And don't forget to free it to prevent memory leaks!
Marshal.FreeHGlobal(myPtr);
EDIT 2.关于“无法获取托管类型的地址、获取其大小或声明指向托管类型的指针”错误 - 您的定义并非完全非托管。不安全的定义和使用编组逻辑的定义并不总是相等;在这里,它认为您的类是“托管”的,因为其中存在数组引用。尝试固定数组:
[StructLayout(LayoutKind.Sequential)]
public unsafe struct tagTimeHistory
{
public uint m_nAction;
public int m_nFlag;
public int m_nRecordNum;
public int m_nTimeStamp;
public int m_nMiscStartIndex;
public fixed float m_pfTHFloatVals[256];
public fixed float m_pfTH11OBAVals[48];
public fixed float m_pfTH13OBAVals[144];
public float m_fDuration;
}