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);

В этом варианте не уверен насчет чтения результата — не совсем ясно кто и выделяет и
и кто должен освобождать память из под возвращаемой функцией структуры
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.