И снова передача структуры с массивом в unmanaged функцию
От: Аноним  
Дата: 27.11.06 07:53
Оценка:
Итак, есть библиотка и в ней некая unmanaged функция Command, с которой надо поработать на C#. К этой функции есть описание и пример работы на VB6.
Public Const POLL_CMD = &H7
Public Const OK = &HF0

' структура определённая пользователем
Public Type UDT
rxStatus As Integer
datalen As Byte
array1(254) As Byte
End Type
Dim Cpy As UDT, Src as UDT

' посылаем команду Poll
Src.datalen = 1
Src.array1(0) = POLL_CMD
Cpy = Command(Src)
If Cpy.array1(0) <> OK Then
MsgBox "Ошибка", vbCritical, App.ProductName
CloseComm
Exit Function
End If
' Cpy.Array1 теперь содержит нужные данные

-==Теперь мои рассуждения

Понятно, что первым делом функцию надо экспортировать. Тут сразу возникает вопрос — её можно экспортировать так


[DllImport("my.dll", CharSet = CharSet.Auto)]
public static extern UDT Command(UDT udt);



или так


[DllImport("my.dll", CharSet = CharSet.Auto)]
public static extern IntPtr Command(IntPtr udt);



Как правильно?

Затем нужно объявить структуру, с которой будем работать, по итогам чтения форума тоже получается два варианта, неясно какой верный (или они оба верны?):

Вариант 1:


    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public class UDT
    {
        [MarshalAs(UnmanagedType.U2)]
        [FieldOffset(0)]
        public ushort rxStatus;
        [MarshalAs(UnmanagedType.U1)]
        [FieldOffset(2)]
        public byte dLen;
        [FieldOffset(3)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
        public byte[] data = new byte[254];
    }




Вариант 2:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class UDT
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort rxStatus;
        [MarshalAs(UnmanagedType.U1)]
        public byte dLen;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
        public byte[] data = new byte[254];
    }



Далее нужно передать переменную в функцию делаю это так:


            UDT cmd = new UDT();
            UDT cpy = new UDT();

            cmd.rxStatus = 0;
            cmd.dLen = 1;
            cmd.data[0] = 1;

            IntPtr pntC = Marshal.AllocHGlobal(Marshal.SizeOf(cmd));
            Marshal.StructureToPtr(cmd, pntC, false);

            IntPtr pntR = Marshal.AllocHGlobal(Marshal.SizeOf(cpy));
            Marshal.StructureToPtr(cpy, pntR, false);
            try
            {
                pntR = Validator.Command(pntC);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                Marshal.FreeHGlobal(pntC);
                Marshal.FreeHGlobal(pntR);

            }


В итоге получаю ошибку, если работает первый вариант структуры

Could not load type 'ValidatorClass.UDT' from assembly 'ValidatorClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 3 that is incorrectly aligned or

overlapped by a non-object field.

Если работаю со втроым вариантом структуры, то получаю такую ошибку

A call to PInvoke function 'ValidatorClass!ValidatorClass.Validator::Command' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

Понятно, что на данном этапе проблема в несоответствии объявленной структуры и сигнатуры метода. Но вроде бы ж всё согласно документации.

Блин, если вы дочитали до конца, то спасибо огромное
А если ещё поможете — double thanx.
Форум я уже читал, но по-моему стало только хуже — добавилось каши в голове.
Буду благодарен за ответ.
И снова передача структуры с массивом в unmanaged функцию
От: Аноним  
Дата: 27.11.06 10:07
Оценка:
Вместо byte[] в структуре используй IntPtr.

Скопируй массив байтов в память при помощи Marshal.Copy
и в структуру передай указатель.

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
Это, естественно, убери потом.

Вот такой вариант должен заработать.
[StructLayout(LayoutKind.Sequential]
    public struct UDT
    {
        public ushort rxStatus;
        public byte dLen;
        public IntPtr data;
    }
Ut semper Leo feriatur!


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Еслм интересно почему не рабоет первый вариант
От: Аноним  
Дата: 27.11.06 10:15
Оценка:
При использование LayoutKind.Sequential желательно MSDN почитатть по StructLayoutAttribute.Pack.
-----
Нулевое оформления постов благодаря Opere.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: И снова передача структуры с массивом в unmanaged функци
От: AThe  
Дата: 27.11.06 10:21
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>
А>' структура определённая пользователем
А>Public Type UDT
А>rxStatus As Integer
А>datalen As Byte
А>array1(254) As Byte
А>End Type
А>Dim Cpy As UDT, Src as UDT
А>

А>-==Теперь мои рассуждения

А>Понятно, что первым делом функцию надо экспортировать. Тут сразу возникает вопрос — её можно экспортировать так


А>
А>    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
А>    public class UDT
А>    {
А>        [MarshalAs(UnmanagedType.U2)]
А>        [FieldOffset(0)]
А>        public ushort rxStatus;
А>        [MarshalAs(UnmanagedType.U1)]
А>        [FieldOffset(2)]
А>        public byte dLen;
А>        [FieldOffset(3)]
А>        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
А>        public byte[] data = new byte[254];
А>    }
А>


А>Буду благодарен за ответ.


Точно не скажу (VB под рукой нет), но, наверно, Integer в VB занимает 4 байта, посему:

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public class UDT
    {
        [MarshalAs(UnmanagedType.U4)]
        [FieldOffset(0)]
        public int rxStatus;
        [MarshalAs(UnmanagedType.U1)]
        [FieldOffset(2)]
        public byte dLen;
        [FieldOffset(3)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
        public byte[] data = new byte[254];
    }
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 10:46
Оценка:
Здравствуйте, AThe, Вы писали:

AT>Точно не скажу (VB под рукой нет), но, наверно, Integer в VB занимает 4 байта, посему:


AT>
AT>    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
AT>    public class UDT
AT>    {
AT>        [MarshalAs(UnmanagedType.U4)]
AT>        [FieldOffset(0)]
AT>        public int rxStatus;
AT>        [MarshalAs(UnmanagedType.U1)]
AT>        [FieldOffset(2)]
AT>        public byte dLen;
AT>        [FieldOffset(3)]
AT>        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
AT>        public byte[] data = new byte[254];
AT>    }
AT>


Тогда здесь

AT> [MarshalAs(UnmanagedType.U1)]

AT> [FieldOffset(2)]


Должно быть

[MarshalAs(UnmanagedType.U1)]
[FieldOffset(4)]

???
Re[3]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 10:53
Оценка:
http://www.gotdotnet.ru/Forums/Common/402051.aspx
Re[4]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 11:04
Оценка:
Сделал вот так


    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public struct UDT
    {
        [MarshalAs(UnmanagedType.U4)]
        [FieldOffset(0)]
        public ushort rxStatus;
        [MarshalAs(UnmanagedType.U1)]
        [FieldOffset(4)]
        public byte datalen;
        [FieldOffset(5)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
        public byte[] data;

        public void Init()
        {
            data = new byte[254];
        }
    }




Ошибка в приницпе всё таже:

Could not load type 'ValidatorClass.UDT' from assembly 'ValidatorClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 5 that is incorrectly aligned or overlapped by a non-object field.
Re[5]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 11:30
Оценка:
Сейчас будет куча тупых вопросов, с указателями не работал уже лет 10, всё вылетело...

Окей, пробую так...

[DllImport("xxx.dll", CharSet = CharSet.Auto)]
public static extern UDT Command(UDT udt);

[StructLayout(LayoutKind.Sequential)]
public struct UDT
{
public ushort rxStatus;
public byte dLen;
public IntPtr data;
}


UDT cmd = new UDT();
cmd.rxStatus = 0;
cmd.dLen = 1;

byte[] data = new byte[254];
data[0] = 1;
IntPtr arPtr = new IntPtr();
>>-----здесь указатель должен куда-то указать, иначе копирование вываливается в исключение
>>-----как выделить память под структуру для указателя?
>>-----только в ФАК не шлите плиз
Marshal.Copy(data, 0, arPtr, 254);
cmd.data = arPtr;
Validator.Command(cmd);
Re[6]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 12:12
Оценка:
Пока сделал так, по крайней мере исключение не выкидывает.


            UDT cmd = new UDT();
            UDT cpy = new UDT();

            cmd.rxStatus = 0;
            cmd.dLen = 1;

            byte[] data = new byte[255];
            data[0] = 1;
            IntPtr arPtr = new IntPtr();
            arPtr = Marshal.AllocHGlobal(255);
            Marshal.Copy(data, 0, arPtr, 255);
            cmd.data = arPtr;
//сейчас поработаю над получением данных, спрошу, если не получится
            Marshal.FreeHGlobal(arPtr);
Re[6]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 12:47
Оценка:
Похоже на правду.
Ut semper Leo feriatur!


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[7]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 17:11
Оценка:
Продолжаем... Что-то не выходит у Данилы каменный цветок.

Сейчас ситуация такая:


[DllImport("xxx.dll", CharSet = CharSet.Auto)]
public static extern UDT Command(UDT udt);

[StructLayout(LayoutKind.Sequential)]    
public struct UDT    
{        
public ushort rxStatus;        
public byte dLen;        
public IntPtr data;    
}



При попытке выполнить функцию ошибку получаем там, где есть комментарий


        private void button5_Click(object sender, EventArgs e)
        {
            UDT cmd = new UDT();
            UDT cpy = new UDT();

            cmd.rxStatus = 0;
            cmd.dLen = 1;

            byte[] dataA = new byte[255];
            byte[] dataB = new byte[255];

            dataA[0] = (byte)ValidatorCodes.SYNC_CMD;
            IntPtr arPtr = new IntPtr();
            arPtr = Marshal.AllocCoTaskMem(255);
            Marshal.Copy(dataA, 0, arPtr, 255);
            cmd.data = arPtr;
            Validator.OpenPort(1);
            cpy = Validator.Command(cmd);
            if (cpy.data != IntPtr.Zero)
            {
---------------->Marshal.Copy(cpy.data, dataB, 0, 255);
                //Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
                MessageBox.Show(dataB[0].ToString());
            }

            Marshal.FreeCoTaskMem(arPtr);
            Validator.CloseComm();

        }


То есть похоже, что

а) либо всё-таки что-то не то с объявлением структуры
б) либо некорректно копируется массив из unmanaged памяти

Пните плиз ещё раз в верном направлении.
Re[8]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 27.11.06 17:39
Оценка:
Нет, со структурой похоже всё ОК.
Тут видимо дело в копировании в массив полученных данных.
Re[9]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 28.11.06 06:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нет, со структурой похоже всё ОК.

А>Тут видимо дело в копировании в массив полученных данных.

Что-то в этом супе не то.

При попытке копирования данных в managed массив выдаётся ошибка
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Причём IntPtr равен 10, т.е. явно такого быть не может.

Есть идеи ещё какие-то?
Re[10]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 07:04
Оценка:
И ещё — почитал я про параметр Pack атрибута StructLayout.
Но конкретного ответа не нашёл на то, каким должно быть его значение при каких условиях.

М.б. причина в том, что структура некорректно накладывается/передаётся?
Подскажет кто?
Re[10]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 07:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Нет, со структурой похоже всё ОК.

А>>Тут видимо дело в копировании в массив полученных данных.

А>Что-то в этом супе не то.


А>При попытке копирования данных в managed массив выдаётся ошибка

А>Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

А>Причём IntPtr равен 10, т.е. явно такого быть не может.


А>Есть идеи ещё какие-то?



Есть подозрение, что в структуре должен храниться не указатель на массив, а сам массив.
В этом случае, получается примерно следующее:

Вариант I
//на паскале это выглядело бы так
type
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
UDT = record
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(0)]
rxStatus : integer;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(4)]
datalen : byte;
[FieldOffset(5)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
data : array[255] of byte;
end;

// на сях видимо будет так
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct UDT
{
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(0)]
public int rxStatus;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(4)]
public byte datalen;
[FieldOffset(5)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public byte[255] data;
}

Вариант II

1)
[DllImport("my.dll", CharSet = CharSet.Auto)]
public static extern IntPtr Command(IntPtr udt);

2)
public class UDT
{
public int rxStatus;
public byte dLen;
public byte[] data;
}

3)
UDT cmd = new UDT();
UDT cpy = new UDT();

cmd.rxStatus = 0;
cmd.dLen = 1;

byte[] dataA = new byte[255];
byte[] dataB = new byte[255];

dataA[0] = (byte)ValidatorCodes.SYNC_CMD;

arPtr = Marshal.AllocHGlobal(4+1+255);
Marshal.WriteInt32(arPtr,0,udt.rxStatus);
Marshal.WriteByte(arPtr,4,udt.dLen);
Marshal.Copy(arPtr, 5, udt.data, 255);
Validator.OpenPort(1);
retPtr = Command(arPtr);

cpy.rxStatus = Marshal.ReadInt32(retPtr,0);
cpy.dLen = Marshal.ReadByte(retPtr,4);
Marshal.Copy(retPtr,5,cpy.dLen,cpy.Data)


Marshal.FreeHGlobal(arPtr);

В этом варианте не уверен насчет чтения результата — не совсем ясно кто и выделяет и
и кто должен освобождать память из под возвращаемой функцией структуры
Re[11]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 07:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Аноним, Вы писали:


А>>>Нет, со структурой похоже всё ОК.

А>>>Тут видимо дело в копировании в массив полученных данных.

А>>Что-то в этом супе не то.


А>>При попытке копирования данных в managed массив выдаётся ошибка

А>>Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

А>>Причём IntPtr равен 10, т.е. явно такого быть не может.


А>>Есть идеи ещё какие-то?



Да чуть не забыл, в Вариант I

private void button5_Click(object sender, EventArgs e)
{
UDT cmd = new UDT();
UDT cpy;

cmd.rxStatus = 0;
cmd.dLen = 1;

cmd.data[0] = (byte)ValidatorCodes.SYNC_CMD;
Validator.OpenPort(1);
cpy = Validator.Command(cmd);
if (cpy.data[0] != OK)
{
MessageBox.Show(...);
}

Validator.CloseComm();

}
Re[12]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 08:30
Оценка:
Нет, блин, не выходит.
Ни так ни этак.
Кроме того, я глянул, что Integer в VB6 2байтовый.
И справил, но лучше не стало.

Вижу, что всё упирается в массив так или иначе. Почему-то он некоректно размещён, хотя вроде бы всё ок.

Непобедимое какое-то...
Re[13]: И снова передача структуры с массивом в unmanaged фу
От: SQWO  
Дата: 28.11.06 08:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нет, блин, не выходит.

А>Ни так ни этак.
А>Кроме того, я глянул, что Integer в VB6 2байтовый.
А>И справил, но лучше не стало.

А>Вижу, что всё упирается в массив так или иначе. Почему-то он некоректно размещён, хотя вроде бы всё ок.


А>Непобедимое какое-то...


Можешь выложить код по Вариант I и где какая ошибка происходит?

PS Это я писал просто теперь зарегистрировался...
Re[14]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 09:12
Оценка:
Вариант 1:

-импорт

    [DllImport("my.dll", CharSet = CharSet.Ansi, EntryPoint="Command")]
    public static extern UDT1 Command1(UDT1 udt);



-объявление класса


    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    public class UDT1
    {
    [MarshalAs(UnmanagedType.U2)]
    [FieldOffset(0)]
    public short rxStatus;
    [MarshalAs(UnmanagedType.U1)]
    [FieldOffset(2)]
    public byte datalen;
    [FieldOffset(3)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
    public byte[] data = new byte[255];
    }



--можно объявить структуру, но тогда массив нужно инициализировать в методе перед вызовом Command

--код простой


            UDT1 cmd = new UDT1();
            UDT1 cpy = new UDT1();

            cmd.rxStatus = 0;
            cmd.datalen = 1;

            cmd.data[0] = (byte)ValidatorCodes.SYNC_CMD;
            cpy = Validator.Command1(cmd);




--ошибка
Could not load type 'ValidatorClass.UDT1' from assembly 'ValidatorClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 3 that is incorrectly aligned or overlapped by a non-object field.

Т.е. массив чем-то левым перекрывается, чем и почему — неясно.

Если есть возможность попробовать, могу выслать саму библиотеку на мыло.
Re[15]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 11:43
Оценка:
После упорных и продолжительных боёв...

На данный момент работает такая конструкция, НЕ генерируя исключений.
Беда одна — в возвращаемой структуре cpy указатель указывает в 0. Т.е. в никуда, а поле datalen=1, т.е. данные в массиве есть,
но указатель на них почему-то не указывает.

Если есть идеи почему, прошу высказаться.

Спасибо



    [DllImport("my.dll", CharSet = CharSet.Ansi, EntryPoint = "Command")]
    public static extern UDT2 Command2(UDT2 cmd);

    [StructLayout(LayoutKind.Sequential)]
    public struct UDT2
    {
        public short rxStatus;
        public byte datalen;
        public IntPtr dataPtr;
    }

//метод...
            UDT2 cmd = new UDT2();
            UDT2 cpy = new UDT2();
            cmd.rxStatus = 0;
            cmd.datalen = 1;

            byte[] dataIn  = new byte[255];
            byte[] dataOut = new byte[255];

            dataIn[0] =  0x11;

            cmd.dataPtr = Marshal.AllocHGlobal(IntPtr.Size);
            Marshal.Copy(dataIn, 0, cmd.dataPtr, cmd.datalen);
            cpy = Fun.Command2(cmd);
            if (cpy.dataPtr != IntPtr.Zero)
            {

            }
            Marshal.FreeHGlobal(cmd.dataPtr);
Re[16]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 11:56
Оценка:
По ходу событий...

Объявляю структуру так


    [StructLayout(LayoutKind.Explicit)]
    public struct UDT3
    {
        [FieldOffset(0)]
        public short rxStatus;
        [FieldOffset(2)]
        public byte datalen;
        [FieldOffset(3)]
        public IntPtr dataPtr;
    }



--генерируется ошибка, а если так

[StructLayout(LayoutKind.Explicit)]
public struct UDT3
{
[FieldOffset(0)]
public short rxStatus;
[FieldOffset(2)]
public byte datalen;
[FieldOffset(4)]
public IntPtr dataPtr;
}

то всё ок, получается byte в памяти 2 байта занимает?
Re[17]: И снова передача структуры с массивом в unmanaged фу
От: Аноним  
Дата: 28.11.06 12:33
Оценка:
Что-то ни одного MVP нет. Повымерли все что ли или вопрос слишком сложный?
Re: И снова передача структуры с массивом в unmanaged функци
От: Аноним  
Дата: 28.11.06 13:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Итак, есть библиотка и в ней некая unmanaged функция Command, с которой надо поработать на C#. К этой функции есть описание и пример работы на


Чтобы не гадать, было бы здорово, если бы вы привели оригинальное описание функции и типов ее параметров.
Re[2]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 28.11.06 13:35
Оценка:
А>Чтобы не гадать, было бы здорово, если бы вы привели оригинальное описание функции и типов ее параметров.

Оригинальное описание из документации

Command
Function title: Command
Parameters: Command structure, UDT
Return value: UDT containing return data. The datalen parameter is the number of bytes in the data array. The data array, array1 contains the return data.
Function Description: Sends an SSP command to an open serial port. The UDT data structure is loaded with the data length (how many bytes in the command array). The command array contains the command and any data. rxStatus is set to the SSP address of the slave device (defaults to 0)

Visual Basic declaration:

Public Declare Function Command Lib "InnTechSSP.dll" (Src As UDT) As UDT
'Example usage for Visual Basic:
Public Const POLL_CMD = &H7
Public Const OK = &HF0
' the user defined structure
Public Type UDT
rxStatus As Integer
datalen As Byte
array1(254) As Byte
End Type
Dim Cpy As UDT, Src as UDT
' send Poll command
Src.datalen = 1
Src.array1(0) = POLL_CMD
Cpy = Command(Src)
If Cpy.array1(0) <> OK Then
MsgBox "Validator comms error", vbCritical, App.ProductName
CloseComm
Exit Function
End If
' Cpy.Array1 now contains the event list for the slave
Re[2]: И снова передача структуры с массивом в unmanaged фун
От: SQWO  
Дата: 28.11.06 14:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Итак, есть библиотка и в ней некая unmanaged функция Command, с которой надо поработать на C#. К этой функции есть описание и пример работы на


А>Чтобы не гадать, было бы здорово, если бы вы привели оригинальное описание функции и типов ее параметров.


А самый рабочий вариант дает поиск в Google


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class UDT
    {
        [MarshalAs(UnmanagedType.U2)]
        public short rxStatus;
        [MarshalAs(UnmanagedType.U1)]
        public byte dLen;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 254)]
        public byte[] data = new byte[254];
    }



        [DllImport("InnTechSSP.dll", CharSet = CharSet.Auto)]
        public static extern int Command(UDT udt, ref UDT cpy);



            UDT cmd = new UDT();
            UDT ret = new UDT();

            cmd.rxStatus = 0;
            cmd.dLen = 1;
            cmd.data[0] = 7;

            try
            {
                Console.WriteLine( "Started" );

                Console.WriteLine( "cmd.rxStatus = " + cmd.rxStatus );
                Console.WriteLine( "cmd.dLen     = " + cmd.dLen );
                Console.WriteLine( "cmd.data[0]  = " + cmd.data[0] );
                Console.WriteLine( "cmd.data[1]  = " + cmd.data[1] );
                Console.WriteLine( "cmd.data[2]  = " + cmd.data[2] );
                Console.WriteLine( "cmd.data[3]  = " + cmd.data[3] );

                
                ValidatorClass.OpenPort( 1 );

                try
                {


                    ValidatorClass.Command( cmd, ref ret );



                        Console.WriteLine( "ret.rxStatus = " + ret.rxStatus );
                              Console.WriteLine( "ret.dLen     = " + ret.dLen );
                        Console.WriteLine( "ret.data[0]  = " + ret.data[0] );
                        Console.WriteLine( "ret.data[1]  = " + ret.data[1] );
                        Console.WriteLine( "ret.data[2]  = " + ret.data[2] );
                        Console.WriteLine( "ret.data[3]  = " + ret.data[3] );
                }
                catch (Exception ex)
                {
                    ValidatorClass.CloseComm();
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine( ex.Message );
                Console.WriteLine( ex.StackTrace );
            }
            Console.WriteLine( "Finished" );
            Console.ReadLine();
Re[3]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 28.11.06 14:32
Оценка:
Сейчас попробую, конечно, но в Google я искал, ничё не нашёл толкового.
Впрочем, сейчас гляну...
Re[4]: И снова передача структуры с массивом в unmanaged фун
От: SQWO  
Дата: 28.11.06 14:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сейчас попробую, конечно, но в Google я искал, ничё не нашёл толкового.

А>Впрочем, сейчас гляну...

Я искал по "InnTechSSP.dll"

в числе прочего нашлось вот это
http://www.developmentnow.com/g/21_2004_11_0_0_9725/problem-converting-code.htm

это вселяет уверенность, что ты не одинок

На том примере, что я привел все работает без исключений как для существующего порта,
так и для несуществующего.

А уж правильность результата — это тебе виднее — у меня в обоих случаях пустой
массив возвратился (dLen = 0).
Re[3]: И снова передача структуры с массивом в unmanaged фун
От: Аноним  
Дата: 28.11.06 14:42
Оценка:
Работает, хотя почему именно так импортируется эта функция — не ясно.

И ещё — данных-то и в этом варианте нет. Т.е. в возвращённой структуре dLen=0 один чёрт, а там что-то должно быть.

Console.WriteLine( "ret.dLen = " + ret.dLen );


Ладно, утро вечера мудренее, с утра уже...
Но все равно спасибо за участие
Большое!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.