opak (abstract) Datentypen in C
Frage
Datei api.h
#include <stdio.h>
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
void trial (try *);
#endif
Datei core.h
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
Datei func.c
#include "api.h"
#include "core.h"
void trial (try *tryvar)
{
tryvar->a = 1;
tryvar->b = 2;
}
Datei main.c
#include "api.h"
int main ()
{
try s_tryvar;
trial(&s_tryvar);
printf("a = %d\nb = %d\n", s_tryvar.a, s_tryvar.b);
}
Wenn ich kompilieren, erhalte ich:
main.c:5: error: storage size of ‘s_tryvar’ isn’t known
Wenn ich in core.h
main.c
um diesen Fehler kommt nicht als Versuch in core.h
definiert ist. Aber ich möchte, dass die Struktur try
zu main.c
versteckt werden - es sollte die Mitglieder try
Struktur nicht kennen. Was bin ich?
Lösung
Das glaube ich nicht, was Sie versuchen ist möglich zu tun. Der Compiler muss wissen, wie groß eine try
Struktur main.c
zu kompilieren ist. Wenn Sie es wirklich undurchsichtig sein wollen, eine generische Zeigertyp machen, und stattdessen die Variable direkt in main()
zu erklären, macht alloc_try()
und free_try()
Funktionen das Erstellen und Löschen zu behandeln.
So etwas wie folgt aus:
api.h:
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
try *alloc_try(void);
void free_try(try *);
int try_a(try *);
int try_b(try *);
void trial (try *);
#endif
core.h:
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
func.c:
#include "api.h"
#include "core.h"
#include <stdlib.h>
try *alloc_try(void)
{
return malloc(sizeof(struct trytag));
}
void free_try(try *t)
{
free(t);
}
int try_a(try *t)
{
return t->a;
}
int try_b(try *t)
{
return t->b;
}
void trial(try *t)
{
t->a = 1;
t->b = 2;
}
main.c:
#include <stdio.h>
#include "api.h"
int main()
{
try *s_tryvar = alloc_try();
trial(s_tryvar);
printf("a = %d\nb = %d\n", try_a(s_tryvar), try_b(s_tryvar));
free_try(s_tryvar);
}
Andere Tipps
Denken Sie, wie die opake FILE Struktur arbeitet in C. Sie nur mit Zeigern arbeiten, und Sie müssen eine Funktion wie fopen () eine Instanz, und eine Funktion wie fclose () zu schaffen, die es zu entsorgen.
Das Problem in main.c ist, hat der Compiler nicht die Definition von struct try
gesehen. Aus diesem Grunde wird der Compiler mit Zeigern beschränkt auf struct try
.
Was Sie tun möchten, ist zwei neue Funktionen zu Ihrem API hinzu:
try *create_try();
void *destroy_try(try *t);
Diese Funktionen werden jeweils malloc und kostenlos anrufen.
Wenn Sie nicht möchten, dass Ihre Struktur nur begrenzen, auf dem Heap zu dürfen, werden Sie es undurchsichtig zu machen müssen aufgeben.
Es gibt einen Weg, etwas zu tun, die technisch nicht genau das, was Sie fordern, soll aber den gleichen Zweck zu halten Ihre Struktur undurchsichtig dienen, während nicht-Heapzuordnung unterstützen.
in api.h, geben Sie eine undurchsichtige Struktur wie folgt:
struct trytag_opaque
{
char data[sizeof(int)*2];
};
Wenn Sie als sein undurchsichtiger wollte, die maximale Größe der Struktur berechnen können über einen beliebigen unterstützten Plattform erforderlich ist, und die Verwendung:
struct trytag_opaque
{
char data[MAX_TRYTAG_SIZE];
};
Dann ist Ihre api.h Funktionsdeklarationen würde wie folgt aussehen:
int try_a(struct trytag_opaque *t)
und Ihre Funktion Code würde wie folgt aussehen:
int try_a(struct trytag_opaque *t_opaque) {
trytag *t = (trytag *)t_opaque;
...
}
und Ihre main.c würde wie folgt aussehen:
#include "api.h"
int main() {
struct trytag_opaque t;
...
try_a(&t);
...
}