"Offsety" parametrów struktury

0

Mam następujący problem/zagadnienie. Definiuję sobie typ

typedef struct{
   int property1;
   int property2;
   gchar property3[20];
} MY_PROPERTIES;

Czy jestem w stanie wyliczyć sobie "offsety" (odległości od początku struktury) ? Tj. potrzebuję wiedzieć ile muszę dodać do wskaźnika pokazującego na początek struktury aby dobrać się do odpowiedniego elementu.
Jednym ze sposobów byłoby (na uzyskanie offsetu np. property2)

MY_PROPERTIES instance;
my_offset = (int) &instance - (int) &instance.property2;

Jednak tutaj mam od razu tworzoną instancję. Czy można to zrobić bez tego etapu?
Nie uśmiecha mi się także wyliczanie kolejnych offsetów za pomocą sizeof'owania wszystkich poprzednich elementów. Np. aby dobrać się do property3

my_offset = sizeof(MY_PROPERTIES.property1)+sizeof(MY_PROPERTIES.property2);

Takich elementów mogę mieć dużo, a zmiana kolejności czy dostawienie nowego-nie-na-końcu wymusza przepisanie takich wyliczeń.
Czy istnieje jakaś wygodniejsza metoda?

0

W C++ (nie w C), pod warunkiem zdefiniowania struktury w poniższy sposób:

struct NAZWA {
// tu jakies pola
int poleA;
int poleB;
};

można zrobić coś takiego z użyciem wskaźników na składowe (które w istocie przechowują offsety). Mają one następującą składnię:

typ NAZWA::*wsk; // NAZWA to nazwa struktury

A tak się ich używa:

NAZWA instA;
int NAZWA::*ptr;
ptr = &NAZWA::poleA;
instA.*ptr = 1; // zapisuje do poleA
ptr = &NAZWA::poleB;
instA.*ptr = 1; // zapisuje do poleB

Oczywiście konieczne będzie zdefiniowanie osobnego wskażnika dla każdego typu danych przechowywanych w strukturze. O ile pamiętam dla takich wskażników nie obowiązują zasady arytmetyki dostępne dla 'zwykłych' wskaźników (nie można zatem pododawać sobie offsetów :) ), nie można także pobrać ich wartości, (poprzez konwersję np. na int).

0
PiVoSoftware napisał(a)

W C++ (nie w C), pod warunkiem zdefiniowania struktury w poniższy sposób:

struct NAZWA {
// tu jakies pola
int poleA;
int poleB;
};

W ten sposób zrobiłeś instancję, czego nie chcę :]

PiVoSoftware napisał(a)

można zrobić coś takiego z użyciem wskaźników na składowe (które w istocie przechowują offsety).
[...]
Oczywiście konieczne będzie zdefiniowanie osobnego wskażnika dla każdego typu danych przechowywanych w strukturze.

Gdzie i jak przechowywać to już mam i to nie jest moim problemem :]

PiVoSoftware napisał(a)

O ile pamiętam dla takich wskażników nie obowiązują zasady arytmetyki dostępne dla 'zwykłych' wskaźników (nie można zatem pododawać sobie offsetów :) ), nie można także pobrać ich wartości, (poprzez konwersję np. na int).
Wartość uzyskuję dodając & (czyli 'prosząc' właśnie o podanie adresu, a nie wartości). Operacje arytmetyczne wykonuje takie jakbym działa na intach stąd rzutowanie typu na int.

0
Elmo napisał(a)
PiVoSoftware napisał(a)

W C++ (nie w C), pod warunkiem zdefiniowania struktury w poniższy sposób:

struct NAZWA {
// tu jakies pola
int poleA;
int poleB;
};

W ten sposób zrobiłeś instancję, czego nie chcę :]

???
Nieprawda, to jest tylko deklaracja, równoważna tej z typedef, z tym że ta druga wywodzi się z C!

Instancję tworzy się tak:

struct NAZWA {
} instancja;
Elmo napisał(a)
PiVoSoftware napisał(a)

O ile pamiętam dla takich wskażników nie obowiązują zasady arytmetyki dostępne dla 'zwykłych' wskaźników (nie można zatem pododawać sobie offsetów :) ), nie można także pobrać ich wartości, (poprzez konwersję np. na int).
Wartość uzyskuję dodając & (czyli 'prosząc' właśnie o podanie adresu, a nie wartości). Operacje arytmetyczne wykonuje takie jakbym działa na intach stąd rzutowanie typu na int.

Chodziło mi o wartość w znaczeniu adres (offset) ;]

Nie można zatem zrobić czegoś takiego:

int Nazwa::*wsk = &Nazwa::costam;
int off = (int) wsk; // nie działa ;(
0
PiVoSoftware napisał(a)
Elmo napisał(a)
PiVoSoftware napisał(a)

W C++ (nie w C), pod warunkiem zdefiniowania struktury w poniższy sposób:

struct NAZWA {
// tu jakies pola
int poleA;
int poleB;
};

W ten sposób zrobiłeś instancję, czego nie chcę :]

???
Nieprawda, to jest tylko deklaracja, równoważna tej z typedef, z tym że ta druga wywodzi się z C!

Instancję tworzy się tak:

struct NAZWA {
} instancja;

Racja, mój błąd.

PiVoSoftware napisał(a)

Chodziło mi o wartość w znaczeniu adres (offset) ;]

Nie można zatem zrobić czegoś takiego:

int Nazwa::*wsk = &Nazwa::costam;
int off = (int) wsk; // nie działa ;(

Tego zapisu nie rozumiem, bo z C++ miałem niewiele styczności. Jeżeli chodzi o zapamiętywanie i odwoływanie się to w C robię to tak:

int a;
a = (int) &name_struct - (int) &name_struct.parameter;

a odwołanie się później do odpowiedniego adresu

(typ_tego_parametru*) ( (int) struct + a);

więc jeśli był to int to mogę zrobić tak

int b;
(int*) ( (int) struct + a) = 6;
b = (int*) ( (int) struct + a);

I chyba się nigdzie nie rąbnąłem ;]
na razie wskaźniki i adres mają tendencję to mylenia mi się kiedy i co dostawiać, żeby było dobrze ;] Na szczęście błedy kompilatora służą tu pomocą :]

1 użytkowników online, w tym zalogowanych: 0, gości: 1