C++
Data Alignment yazısına taşıdım.
alignof metodu
alignof yazısına taşıdım.
alignas metodu
alignas ile bir verinin nasıl align edilmesini istediğimizi belirtiriz. POD içindeki bir alan yüzünden fazlaca yer israf ediliyorsa kullanılabilir. Örnek:
11 byte kullanılması gerekirken, 8 byte alan yüzünden 8'in katı olan 24 byte'lık alan ayırılır.
Daha az alan kullanmak için nasıl align edilmesi gerektiği alignas ile belirtirlir.
offsetof metodu
struct içindeki alanın kaçıncı byte'tan başladığını belirtir. Örnek:
struct Test
{
short data1; //2
short data2; //2
char[4] pad1;//4
double data3;//8
}
offsetof macrosu sadece standard layout olan sınıflarda kullanılabilir. Bu macro ile encapsulation kırılabilir. Örnekte private olan bir nesnenin value alanına erişilebiliyor.
gcc ile kullanılır. Padleme yapma anlamına gelir. Şöyle yaparız.
pragma pack
Microsoft ve gcc platformunda kullanılır. Pragma'ya verilen sayıdan büyük olan alanlar verilen sayıya göre hizalanır. Eğer alan pragma sayısından küçükse bir şey yapılmaz.
Verinin 1 byte olarak hizalanması için örnek:
C#
Interop ile C++ kodlarını çağırırken struct'lara müdahale etmek mümkün.
MarshalAs Anotasyonu
Bu anotasyon managed ve unmanaged kod arasında, belleğin nasıl dönüştürüleceğini UnmanagedType enumeration ile kontrol eder.
Dikkatli olunması gereken nokta boolean tipi. Boolean 1 byte değildir. Diğer tiplerde sorun çıkmaz. Mesela aşağıdaki byte[] 3 byte büyüklüğündedir.
UnmanagedType çeşitleri
Örnek:
ByValTStr
C tarzı karakter arrayleri için kullanılır.
ByValArray
Primitive bir tip array'i tanımlamak için kullanılır.
Data Alignment yazısına taşıdım.
alignof metodu
alignof yazısına taşıdım.
alignas metodu
alignas ile bir verinin nasıl align edilmesini istediğimizi belirtiriz. POD içindeki bir alan yüzünden fazlaca yer israf ediliyorsa kullanılabilir. Örnek:
struct st
{
short a; //2 byte
int *b; // 8 byte (64 bit işletim sistemi)
char ch;//1 byte
};
11 byte kullanılması gerekirken, 8 byte alan yüzünden 8'in katı olan 24 byte'lık alan ayırılır.
Daha az alan kullanmak için nasıl align edilmesi gerektiği alignas ile belirtirlir.
struct alignas(char) aligned_structBu durumda 12 byte'lık alan ayırılır. VS 2012 alignas'i desteklemiyor!
{
short a;
int *b;
char ch;
};
offsetof metodu
struct içindeki alanın kaçıncı byte'tan başladığını belirtir. Örnek:
struct Teststruct Test {short data1, short data2, double data3} ile offsetlerin şöyle başladığı gözlemlenebilir.
{
char data1;
char data2;
}
cout << offsetof (Test,data1); // 0 verir
cout << offsetof (Test,data2); // 2 verir
struct Test
{
short data1; //2
short data2; //2
char[4] pad1;//4
double data3;//8
}
offsetof macrosu sadece standard layout olan sınıflarda kullanılabilir. Bu macro ile encapsulation kırılabilir. Örnekte private olan bir nesnenin value alanına erişilebiliyor.
#include<iostream>
using namespace std;
class A
{
int value;
public:
A(){value = 1;}
~A(){}
void print(){cout << value << endl;}
};
int main()
{
A a;
int* p = (int*)(&a);
*p = 20;
a.print();//output is 20.
}
__attributed__((packed))gcc ile kullanılır. Padleme yapma anlamına gelir. Şöyle yaparız.
struct __attribute__((__packed__)) structure
{
int id1;
char name;
int id2;
char c;
float percentage;
};
pragma pack
Microsoft ve gcc platformunda kullanılır. Pragma'ya verilen sayıdan büyük olan alanlar verilen sayıya göre hizalanır. Eğer alan pragma sayısından küçükse bir şey yapılmaz.
Verinin 1 byte olarak hizalanması için örnek:
#pragma pack(push, 1)
typedef struct {
unsigned char __reserved : 1;
unsigned char dont_fragment : 1;
unsigned char more_fragment : 1;
unsigned short fragment_offset : 13;
} ipv4_fragmenting;
#pragma pack(pop)
Şöyle de yapılabilir.#pragma pack(1)
typedef struct {
unsigned char __reserved : 1;
unsigned char dont_fragment : 1;
unsigned char more_fragment : 1;
unsigned short fragment_offset : 13;
} ipv4_fragmenting;
#pragma pack()
Bir başka örnekte veri 4 byte olarak hizalanıyor.
#pragma pack(push,4)
struct MyStruct
{
uint32_t i1; /* offset=0 size=4 */
uint32_t i2; /* offset=4 size=4 */
uint16_t s1; /* offset=8 size=2 */
unsigned char c[8]; /* offset=10 size=8 */
uint16_t s2; /* offset=18 size=2 */
uint16_t s3; /* offset=20 size=2 */
/* offset=22 padding=2 (needed to align MyStruct) */
} ; // total size is 24
C#
Interop ile C++ kodlarını çağırırken struct'lara müdahale etmek mümkün.
MarshalAs Anotasyonu
Bu anotasyon managed ve unmanaged kod arasında, belleğin nasıl dönüştürüleceğini UnmanagedType enumeration ile kontrol eder.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct PSTSensor
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string name;
public int id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public float[] pose;
public double timestamp;
}
Tiplerin BüyüklüğüDikkatli olunması gereken nokta boolean tipi. Boolean 1 byte değildir. Diğer tiplerde sorun çıkmaz. Mesela aşağıdaki byte[] 3 byte büyüklüğündedir.
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct struct1
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] values;
}
Çıktı olarak 3 alırız.Console.WriteLine("sizeof array of bytes: "+Marshal.SizeOf(typeof(struct1)));
Ancak boolean array 12 byte büyüklüğündedir[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct struct2
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public bool[] values;
}
Çıktı olarak 12 alırız.Console.WriteLine("sizeof array of bools: " + Marshal.SizeOf(typeof(struct2)));
UnmanagedType çeşitleri
Örnek:
ByValTStr
C tarzı karakter arrayleri için kullanılır.
ByValArray
Primitive bir tip array'i tanımlamak için kullanılır.
Hiç yorum yok:
Yorum Gönder