For struct, set the layoutkind (e.g. sequential, offset, etc),
    [StructLayout(LayoutKind.Sequential, Pack=8)]

For datatype, use MarshalAs,
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public STRUCT_B [] struct_b;      /* reference other structs if needed */

        [DllImport(“some.dll”, CharSet = CharSet.Ansi, EntryPoint = “SomeApi”)]
        internal static extern int MyApi(
            [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder sb1,
            [In, MarshalAs(UnmanagedType.LPStr)] string str1,
            [In, MarshalAs(UnmanagedType.LPStr)] string str2,
            [In, MarshalAs(UnmanagedType.LPStr)] string str3,
            [In, MarshalAs(UnmanagedType.LPArray)] string[] str4);

Struct example:
    [StructLayout(LayoutKind.Sequential, Pack=4)]
    public struct SOME_REC
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] some_id;           /* id */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] some_data;          /* data */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public OTHER_STRUCT[] other_struct;      /* other struct */

The following link has the unmanaged types lookup: