Как исправить System.TypeLoadException при объявлении структур с объединением? - PullRequest
0 голосов
/ 17 января 2019

Получение System.TypeLoadException во время выполнения. Я использую код из стороннего источника для определения структур и p-вызова внешних методов.

Я нашел полный код онлайн в этой ссылке.

В коде есть некоторые структуры с объединением, использующие FieldOffsetAttribute(0) для нескольких полей. когда я пытаюсь использовать некоторые структуры, я получаю исключение:

Не удалось загрузить тип 'NET_DVR_SLAVE_CHANNEL_UNION' из сборки 'ClassLibrary1, версия = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null', поскольку он содержит поле объекта со смещением 0, которое неправильно выровнено или перекрыто полем не-объекта .

Я создал пример проекта, который воспроизводит это поведение, используя две структуры из исходного файла.

этот код работал, после того как я разделил приложение на две разные сборки и динамически загрузил сборку, содержащую сторонний код, и использовал отражение, чтобы получить типы из загруженной сборки. это заставляло загружать типы и вызывало ошибку, до сих пор эти типы не использовались, поэтому мы не знали о проблеме.

В качестве временного решения я удалил эти типы из кода.

Сотрудник предположил, что некоторые поля являются «блицбликовыми», ссылаясь на байтовые массивы. Но эти поля украшены атрибутом MarshalAsAttribute, так что, думаю, с этим все должно получиться.

{using System.Runtime.InteropServices;
namespace ClassLibrary1
{
    public class Class1
    {
        public const int MAX_DOMAIN_NAME = 64;
        public const int NAME_LEN = 32;
        public const int PASSWD_LEN = 16;

        [StructLayoutAttribute(LayoutKind.Sequential)]
        public struct NET_DVR_CHANNEL
        {
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_DOMAIN_NAME, ArraySubType = UnmanagedType.I1)]
            public byte[] byAddress;
            public ushort wDVRPort;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes1;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
            public byte[] sUserName;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
            public byte[] sPassword;
            public uint dwChannel;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes2;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct NET_DVR_SLAVE_CHANNEL_UNION
        {
            [FieldOffsetAttribute(0)]
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 152, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes;
            [FieldOffsetAttribute(0)]
            public uint dwLocalChannel;
            [FieldOffsetAttribute(0)]
            public NET_DVR_CHANNEL struRemoteChannel;
        }
    }
}
}


using static ClassLibrary1.Class1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            NET_DVR_CHANNEL instance_NET_DVR_CHANNEL;
            NET_DVR_SLAVE_CHANNEL_UNION instance_NET_DVR_SLAVE_CHANNEL_UNION;
        }
    }
}

Можно ли решить эту проблему, добавив атрибут MarshalAsAttribute в NET_DVR_CHANNEL?

примеры кода и / или направление меня к объяснению того, как решить эту проблему, будет высоко ценится. Кроме того, с удовольствием будет получено объяснение того, что не так в коде.

...