Возможно задаю банальный вопрос, но потратил уйму времени и не нашел ответа(
Получаю из БД массив byte[] состоящий из 42 байтов, а именно
public struct WKBPoint
{
public byte byteOrder;
public UInt32 wkbType;
public Point point;
}
...
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
//здесь хочу как с С++
//WKBPoint* p;
//p=&dr[0];
}
я так понимаю в управляемом коде это невозможно, но как то же решается? Объемы большие и копирование не желательно, если это не единственный выход
How to: Create a C/C++ Union Using Attributes (C# Programming Guide)
By using attributes you can customize how structs are laid out in memory. For example, you can create what is known as a union in C/C++ by using the StructLayout(LayoutKind.Explicit) and FieldOffset attributes.
Example
In this code segment, all of the fields of TestUnion start at the same location in memory.
[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestUnion
{
[System.Runtime.InteropServices.FieldOffset(0)]
public int i;
[System.Runtime.InteropServices.FieldOffset(0)]
public double d;
[System.Runtime.InteropServices.FieldOffset(0)]
public char c;
[System.Runtime.InteropServices.FieldOffset(0)]
public byte b;
}
The following is another example where fields start at different explicitly set locations.
[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestExplicit
{
[System.Runtime.InteropServices.FieldOffset(0)]
public long lg;
[System.Runtime.InteropServices.FieldOffset(0)]
public int i1;
[System.Runtime.InteropServices.FieldOffset(4)]
public int i2;
[System.Runtime.InteropServices.FieldOffset(8)]
public double d;
[System.Runtime.InteropServices.FieldOffset(12)]
public char c;
[System.Runtime.InteropServices.FieldOffset(14)]
public byte b;
}
The two int fields, i1 and i2, share the same memory locations as lg. This sort of control over struct layout is useful when using platform invocation.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
Здравствуйте, Makmen, Вы писали:
M>я так понимаю в управляемом коде это невозможно, но как то же решается? Объемы большие и копирование не желательно, если это не единственный выход
Если беспокоит производительность, то можно передавать в методы структуры по ссылке, тогда копирования производиться не будет.
private void Use(ref WKBPoint item)
Если структура больше 16 байт как в вашем случае, лучше вместо структуры использовать класс, производительность будет лучше и в метод будет всегда передаваться ссылка на объект.
Здравствуйте, AndrewVK,
Я пишу так :
[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
public class WKBPoint
{
[System.Runtime.InteropServices.FieldOffset(0)]
public byte[] bytesIn ;
[System.Runtime.InteropServices.FieldOffset(0)]
public byte byteOrder;
[System.Runtime.InteropServices.FieldOffset(1)]
public UInt32 wkbType;
[System.Runtime.InteropServices.FieldOffset(5)]
public Point point;
}
затем:
NpgsqlDataReader dr = command.ExecuteReader();
WKBPoint wpnt; ;
while (dr.Read())
{
wpnt = new WKBPoint();
wpnt.bytesIn = (byte[])dr[0];
e.Graphics.DrawIcon(ic, new Rectangle(wpnt.point, citySize));
}
Получаю ошибку :
Could not load type 'WKBPoint' from assembly 'ClientPlace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
Я так понимаю дело в массиве byte[] bytesIn, как решить эту проблему ?
Здравствуйте, Makmen, Вы писали:
M>Я так понимаю дело в массиве byte[] bytesIn, как решить эту проблему ?
Попробуй так:
[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
public class WKBPoint
{
[System.Runtime.InteropServices.FieldOffset(0)]
publicfixedbyte[42] bytesIn ;
[System.Runtime.InteropServices.FieldOffset(0)]
public byte byteOrder;
[System.Runtime.InteropServices.FieldOffset(1)]
public UInt32 wkbType;
[System.Runtime.InteropServices.FieldOffset(5)]
public Point point;
}
P.S. Код, чтобы он читался, следует выделять соотв. тегом.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
Как быстрое и простое решение можно обернуть свою структуру классом и везде передавать ссылку на нее:
public struct MyStruct
{
public int Data;
}
public class MyStructRef
{
public MyStruct Ref;
public MyStructRef(MyStruct r)
{
Ref = r;
}
}
...........
MyStructRef p = new MyStructRef(myStruct);
Program.SomeMethod(p);
Исли нужно передавать разные структуры, можно реализовать через дженерик (сделай поиск по форуму, уже писали об этом)