I'm trying to use P/Invoke Interop Assistant to call a C++ Dll in C#. Most of the header is converted fine but I'm having trouble with this:
#define FULLOCTAVE_BINS 12
#define THIRDOCTAVE_BINS 36
typedef struct tagTimeHistory
{
UINT m_nAction;
int m_nFlag;
int m_nRecordNum;
int m_nTimeStamp;
int m_nMiscStartIndex;
float m_pfTHFloatVals[256]; // Number of valid values given by m_nNumFloatVals in Settings.
float m_pfTH11OBAVals[4][FULLOCTAVE_BINS]; // 0-4 spectra given by m_nNumOBA11Vals in Settings
float m_pfTH13OBAVals[4][THIRDOCTAVE_BINS]; // 0-4 spectra given by m_nNumOBA13Vals in Settings
float m_fDuration;
} stTimeHistory_t;
typedef struct tagSlmBulkRecords
{
int nRecType;
union
{
stTimeHistory_t *m_ThRecs;
stInterval_t *m_Interval;
stExceedence_t *m_Exceedences;
stRunRecord_t *m_RunRecord;
stSpeechData_t *m_VoiceRecord;
stSpeechData_t *m_AudioRecord;
};
} stSlmBulkRecord_t;
This is being converted to:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
public struct Anonymous_d2bf9406_c664_4664_9196_800cc23f445a {
/// stTimeHistory_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_ThRecs;
/// stInterval_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_Interval;
/// stExceedence_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_Exceedences;
/// stRunRecord_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_RunRecord;
/// stSpeechData_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_VoiceRecord;
/// stSpeechData_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_AudioRecord;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tagSlmBulkRecords {
/// int
public int nRecType;
/// Anonymous_d2bf9406_c664_4664_9196_800cc23f445a
public Anonymous_d2bf9406_c664_4664_9196_800cc23f445a Union1;
}
But how do I use m_ThRecs when it's just a System.IntPtr? Is there some way of explicitly declaring it to be a pointer to stTimeHistory_t? The C++ code I'm porting to C# uses it like this:
stSlmBulkRecord_t bulkRecord;
bulkRecord.m_ThRecs = new stTimeHistory_t[dataCounts.m_nNumTH];
but if I try this in C#:
tagSlmBulkRecords bulkRecord;
bulkRecord.Union1.m_ThRecs = new tagTimeHistory[dataCounts.m_nNumTH];
I get:
Error 1 Cannot implicitly convert type 'SlmTest.Program.tagTimeHistory[]' to 'SlmTest.Program.tagTimeHistory'"
If I try an unsafe definition:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tagTimeHistory
{
/// UINT->unsigned int
public uint m_nAction;
/// int
public int m_nFlag;
/// int
public int m_nRecordNum;
/// int
public int m_nTimeStamp;
/// int
public int m_nMiscStartIndex;
/// float[256]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 256, ArraySubType = System.Runtime.InteropServices.UnmanagedType.R4)]
public float[] m_pfTHFloatVals;
/// float[48]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 48, ArraySubType = System.Runtime.InteropServices.UnmanagedType.R4)]
public float[] m_pfTH11OBAVals;
/// float[144]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 144, ArraySubType = System.Runtime.InteropServices.UnmanagedType.R4)]
public float[] m_pfTH13OBAVals;
/// float
public float m_fDuration;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
public unsafe struct Anonymous_d2bf9406_c664_4664_9196_800cc23f445a
{
/// stTimeHistory_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public tagTimeHistory *m_ThRecs;
/// stInterval_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr *m_Interval;
/// stExceedence_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_Exceedences;
/// stRunRecord_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_RunRecord;
/// stSpeechData_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_VoiceRecord;
/// stSpeechData_t*
[System.Runtime.InteropServices.FieldOffsetAttribute(0)]
public System.IntPtr m_AudioRecord;
}
I get:
error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type