Avatar billede soreno Praktikant
01. september 2002 - 19:19 Der er 7 kommentarer og
1 løsning

pointer hack

hvis jeg har en struct der består af ca. 25-30 char[] af forskellig størrelse (ialt består den af 2048bytes) og har en anden struct der består af 2 unsigned char[] og ca. 8 char[] (også forskellig størrelse, ialt 34bytes) hvordan gør jeg så flg.:

struct1 s1; //2048bytes
struct2 *s2; //34bytes

s2 = &s1.element;

jeg ved at s2 passer med s1.element (har samme størrelse) og ønsker et hack der gør at jeg direkte kan få s2 til at pege på s1.element

jeg har prøvet at typecaste, men det dur ikke.
Avatar billede jespernaur Nybegynder
01. september 2002 - 19:37 #1
Det du gør burde kunne bringes til at virke med en passende typecastning. Hvordan ser din mislykkede typecastning ud? Og hvordan ser de fulde erklæringer af struct1 og struct2 ud?
Avatar billede soreno Praktikant
01. september 2002 - 19:46 #2
ok, de er lidt lange, og en del af "iso9660.h":
#define ISODCL(from, to) (to - from + 1)
struct iso_directory_record {
    unsigned char length        [ISODCL (1, 1)];  /* 711 */
    char ext_attr_length        [ISODCL (2, 2)];  /* 711 */
    char extent            [ISODCL (3, 10)];  /* 733 */
    char size            [ISODCL (11, 18)]; /* 733 */
    char date            [ISODCL (19, 25)]; /* 7 by 711 */
    char flags            [ISODCL (26, 26)];
    char file_unit_size        [ISODCL (27, 27)]; /* 711 */
    char interleave            [ISODCL (28, 28)]; /* 711 */
    char volume_sequence_number    [ISODCL (29, 32)]; /* 723 */
    unsigned char name_len        [ISODCL (33, 33)]; /* 711 */
    char name            [MAX_ISONAME+1]; /* Not really, but we need something here */
};

struct iso_primary_descriptor {
    char type            [ISODCL (  1,  1)]; /* 711 */
    char id                [ISODCL (  2,  6)];
    char version            [ISODCL (  7,  7)]; /* 711 */
    char unused1            [ISODCL (  8,  8)];
    char system_id            [ISODCL (  9,  40)]; /* achars */
    char volume_id            [ISODCL ( 41,  72)]; /* dchars */
    char unused2            [ISODCL ( 73,  80)];
    char volume_space_size        [ISODCL ( 81,  88)]; /* 733 */
    char escape_sequences        [ISODCL ( 89, 120)];
    char volume_set_size        [ISODCL (121, 124)]; /* 723 */
    char volume_sequence_number    [ISODCL (125, 128)]; /* 723 */
    char logical_block_size        [ISODCL (129, 132)]; /* 723 */
    char path_table_size        [ISODCL (133, 140)]; /* 733 */
    char type_l_path_table        [ISODCL (141, 144)]; /* 731 */
    char opt_type_l_path_table    [ISODCL (145, 148)]; /* 731 */
    char type_m_path_table        [ISODCL (149, 152)]; /* 732 */
    char opt_type_m_path_table    [ISODCL (153, 156)]; /* 732 */
    char root_directory_record    [ISODCL (157, 190)]; /* 9.1 */
    char volume_set_id        [ISODCL (191, 318)]; /* dchars */
    char publisher_id        [ISODCL (319, 446)]; /* achars */
    char preparer_id        [ISODCL (447, 574)]; /* achars */
    char application_id        [ISODCL (575, 702)]; /* achars */
    char copyright_file_id        [ISODCL (703, 739)]; /* 7.5 dchars */
    char abstract_file_id        [ISODCL (740, 776)]; /* 7.5 dchars */
    char bibliographic_file_id    [ISODCL (777, 813)]; /* 7.5 dchars */
    char creation_date        [ISODCL (814, 830)]; /* 8.4.26.1 */
    char modification_date        [ISODCL (831, 847)]; /* 8.4.26.1 */
    char expiration_date        [ISODCL (848, 864)]; /* 8.4.26.1 */
    char effective_date        [ISODCL (865, 881)]; /* 8.4.26.1 */
    char file_structure_version    [ISODCL (882, 882)]; /* 711 */
    char unused4            [ISODCL (883, 883)];
    char application_data        [ISODCL (884, 1395)];
    char unused5            [ISODCL (1396, 2048)];
};

iso_primary_descriptor ipd;
iso_directory_record *root_dir;
root_dir = &ipd.root_directory_record;
Avatar billede jespernaur Nybegynder
01. september 2002 - 20:23 #3
Jeg har lavet det til et 'komplet' program, og jeg var også lige nødt
til at definere MAX_ISONAME, hvor jeg valgte det tilfældige tal 10.
Det interessante står nederst.

Mvh
Jesper Naur


#define MAX_ISONAME 10

#define ISODCL(from, to) (to - from + 1)
struct iso_directory_record {
    unsigned char length        [ISODCL (1, 1)];  /* 711 */
    char ext_attr_length        [ISODCL (2, 2)];  /* 711 */
    char extent            [ISODCL (3, 10)];  /* 733 */
    char size            [ISODCL (11, 18)]; /* 733 */
    char date            [ISODCL (19, 25)]; /* 7 by 711 */
    char flags            [ISODCL (26, 26)];
    char file_unit_size        [ISODCL (27, 27)]; /* 711 */
    char interleave            [ISODCL (28, 28)]; /* 711 */
    char volume_sequence_number    [ISODCL (29, 32)]; /* 723 */
    unsigned char name_len        [ISODCL (33, 33)]; /* 711 */
    char name            [MAX_ISONAME+1]; /* Not really, but we need something here */
};

struct iso_primary_descriptor {
    char type            [ISODCL (  1,  1)]; /* 711 */
    char id                [ISODCL (  2,  6)];
    char version            [ISODCL (  7,  7)]; /* 711 */
    char unused1            [ISODCL (  8,  8)];
    char system_id            [ISODCL (  9,  40)]; /* achars */
    char volume_id            [ISODCL ( 41,  72)]; /* dchars */
    char unused2            [ISODCL ( 73,  80)];
    char volume_space_size        [ISODCL ( 81,  88)]; /* 733 */
    char escape_sequences        [ISODCL ( 89, 120)];
    char volume_set_size        [ISODCL (121, 124)]; /* 723 */
    char volume_sequence_number    [ISODCL (125, 128)]; /* 723 */
    char logical_block_size        [ISODCL (129, 132)]; /* 723 */
    char path_table_size        [ISODCL (133, 140)]; /* 733 */
    char type_l_path_table        [ISODCL (141, 144)]; /* 731 */
    char opt_type_l_path_table    [ISODCL (145, 148)]; /* 731 */
    char type_m_path_table        [ISODCL (149, 152)]; /* 732 */
    char opt_type_m_path_table    [ISODCL (153, 156)]; /* 732 */
    char root_directory_record    [ISODCL (157, 190)]; /* 9.1 */
    char volume_set_id        [ISODCL (191, 318)]; /* dchars */
    char publisher_id        [ISODCL (319, 446)]; /* achars */
    char preparer_id        [ISODCL (447, 574)]; /* achars */
    char application_id        [ISODCL (575, 702)]; /* achars */
    char copyright_file_id        [ISODCL (703, 739)]; /* 7.5 dchars */
    char abstract_file_id        [ISODCL (740, 776)]; /* 7.5 dchars */
    char bibliographic_file_id    [ISODCL (777, 813)]; /* 7.5 dchars */
    char creation_date        [ISODCL (814, 830)]; /* 8.4.26.1 */
    char modification_date        [ISODCL (831, 847)]; /* 8.4.26.1 */
    char expiration_date        [ISODCL (848, 864)]; /* 8.4.26.1 */
    char effective_date        [ISODCL (865, 881)]; /* 8.4.26.1 */
    char file_structure_version    [ISODCL (882, 882)]; /* 711 */
    char unused4            [ISODCL (883, 883)];
    char application_data        [ISODCL (884, 1395)];
    char unused5            [ISODCL (1396, 2048)];
};

void main(void)
{
  struct iso_primary_descriptor ipd;
  struct iso_directory_record *root_dir;
  root_dir = (struct iso_directory_record *)&ipd.root_directory_record;
}
Avatar billede soepro Nybegynder
02. september 2002 - 11:26 #4
soreno >> Altså netop en typecast, sådan som du oprindeligt forsøgte. Du kan ALTID få en pointer af een type til at pege på indholdet i en anden type, ved først at caste til en int (long hvis du anvender gamle DOS-compilere) sådan her:

typedefA *ptrA;
typedefB *ptrB; // typedefB er en delmængde af typedefA's indhold - 712 bytes inde i.

ptrA = (typedefB *)((int)*ptrA+712);
Avatar billede soreno Praktikant
02. september 2002 - 15:27 #5
du mener vel:
ptrB = (typedefB *)((int)*ptrA+712);
?

eller som mit ville/skulle se ud:
iso_primary_descriptor *ipd;
iso_directory_record *root_dir;
root_dir = (struct iso_directory_record *)((int)*ipd+156); //linie 19

men så får jeg en:
main_test.cpp: In function `int main(int, char **)':
main_test.cpp:19: `struct iso_primary_descriptor' used where a `int' was expected

hvorfor det ?
Avatar billede soepro Nybegynder
04. september 2002 - 08:47 #6
Ad 1) Ja, der mangler vist en slut-parentes.

Ad 2) Dette her fungerer:

  typedef struct
  {
    char a;
    int b;
  } typedefA;
  typedef struct
  {
    int c;
  } typedefB;

  typedefA  varA;
  typedefA *ptrA = &varA;
  typedefB *ptrB;

  ptrB = (typedefB *)((int)ptrA + sizeof(int));

Jeg skal selvfølgelig ikke de-reference ptrB pointeren - det giver jo indholdet af typedefA.
Avatar billede soreno Praktikant
04. september 2002 - 14:21 #7
jeg tror ikke helt jeg har forstået..:

(int)ptrA giver start adressen til varA
den adresse lægger jeg sizeof(int) til, men hvad får jeg udaf det.. ?
typedefA indeholder en char(8bit) og en int(32bit).

Så giver det vel: startadressen på varA + 32bit == de 8 sidste bit af int'en i typedefA ?

altså må de sidste 24bit i ptrB->c være garbage ?
eller er det fordi du mener:
  typedef struct
  {
    char c;
  } typedefB;

?
Avatar billede soepro Nybegynder
04. september 2002 - 15:39 #8
My mistake >> Det er selvfølgelig sizeof(C1.a) dvs. sizeof(char) der skulle have stået. Hermed kommer ptrB->c til at pege på ptrA->b.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester