I have an unmanaged static library (.dll) written in C ++:
// This is a personal academic project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C
The GetMyData method returns a pointer to a MyData object.
I imported this library into C # projct using "PInvoke" and called the GetMyData method.
// This is a personal academic project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Explicit)] public class MyData { [FieldOffset(0)] public Int32 index; [FieldOffset(4)] public String name; //[FieldOffset(8)] //public Byte[] data; }; class Program { [DllImport("TestCpp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr GetMyData(); public static void Main(string[] args) { // Call 'GetMyData' method and get structure from pointer using marshaling. var ptr = GetMyData(); var ms = Marshal.PtrToStructure<MyData>(ptr); // Print my data into console var str = ms.index.ToString(); str += ", " + ms.name; //str += ", [" + string.Join(", ", ms.data) + "]"; Console.WriteLine(str); Console.ReadKey(); } }
This code works fine, but if I uncomment the use of the 'data' member of type MyData (in C ++ and C #), I will get an exception in the C # code on this line:
var ms = Marshal.PtrToStructure (ptr);
Error: System.Runtime.InteropServices.SafeArrayTypeMismatchException:
'A mismatch occurred between the runtime type of the array and the subtype recorded in the metadata.'
As I understand it, the offset argument in the FieldOffset attribute is the shift in bytes in unmanaged memory during the conversion of an unmanaged C ++ object to a C # managed object.
The "index" field is 4 bytes in size because it is a 32-bit type.
The 'name' field is a pointer to a char array. For 32-bit architecture, this is also a 32-bit number (4 bytes).
What offset in the 'FieldOffset' attribute do I need to use for the 'data' field?