[C] Przekazywanie dwóch różnych struktur do jednej funkcji

0

Witam,

Zaciąłem się na takim przypadku.

Są dwie struktury danych o podobnej budowie, różnią się tylko długością bufora.
Problem w tym, że muszę powielać wszystkie funkcje obsługujące te dane
ponieważ nie mogę przekazać do funkcji innego typy danych (buffer_t, sbuffer_t)

Jak zrobić, żeby można wywoływać zawsze tą samą funkcję niezależnie od
przekazanej struktury?

Pozdrawiam,
sworduke

//struktury

typedef struct sbuffer_t sbuffer_t;
struct sbuffer_t {
  char data[10];
  uint8_t index;
	uint16_t counter;
};

typedef struct buffer_t buffer_t;
struct buffer_t {
  char data[20];
  uint8_t index;
	uint16_t counter;
};

//definicja zmiennych

buffer_t XXX;
sbuffer_t YYY;

//funkcje

void buffer_init(buffer_t *buffer) {
  buffer->data[0] = '\0';
  buffer->index = 0;
  buffer->counter = 0;
}

void sbuffer_init(sbuffer_t *buffer) {
  buffer->data[0] = '\0';
  buffer->index = 0;
  buffer->counter = 0;
}

//wywolanie

buffer_init(XXX);
sbuffer_init(YYY);

0
  1. zmień kolejność danych, dane, które się różnią na końcu, na początku te, które są identyczne
  2. wprowadz daną z informacją o rozmiarze bufora
  3. rzutuj.
0

Nie bardzo rozumiem dlaczego nie możesz użyć jednej struktury danych.

struct buffer {
    uint8_t index;
    uint16_t counter;
    uint32_t capacity;
    char data[];
};
typedef struct buffer buffer_t;

buffer_t* buffer_alloc(uint32_t capacity) 
{
    buffer_t *b = calloc(1, sizeof(buffer_t) + capacity*sizeof(data[0]));
    if (b != NULL) {
        b->capacity = capacity;
    }
    return b;
}

Wyrównaniem zajmie się kompilator, ponieważ taka konstrukcja i alokacja jest zgodna ze specyfikacją C99.

1

Może unie? Wprowadź do struktury pole, które będzie identyfikowało rodzaj bufora i unię, która będzie definiowała różny rozmiar bufora.

struct buffer_t {
  int bufferType;
  uint8_t index;
  uint16_t counter;
  union {
	char buf_1[20];
	char buf_2[30];
  } data;
};

Albo jakąś strukturę, która opakuje Ci bufor?

struct MojBufor {
  int type;
  int size;
  char *data;
};

struct buffer_t {
  uint8_t index;
  uint16_t counter;
  MojBufor *xyz;
};
0

Jeżeli kod z pierwszego posta Ci się kompiluje to to nie jest C, no ale mniejsza.
Nie znam się na dobrych praktykach w C, ale jeżeli nie brzydzą Cie makra to można tak ideone.

#include <stdio.h>

typedef struct sbuffer_t sbuffer_t;
struct sbuffer_t {
  char data[10];
  int index;
  int counter;
};

typedef struct buffer_t buffer_t;
struct buffer_t {
  char data[20];
  int index;
  int counter;
};

#define NULLZERO ('\0')
#define INIT(name)                    \
void name ## _init(struct name *ptr){ \
  ptr->data[0] = NULLZERO;            \
  ptr->index = 0;                     \
  ptr->counter = 0;                   \
}

INIT(buffer_t);
INIT(sbuffer_t);
//definicja zmiennych

buffer_t XXX;
sbuffer_t YYY;

int main(void) {
	buffer_t_init(&XXX);
	sbuffer_t_init(&YYY);
	return 0;
}
0
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

// Kompilować w trybie zgodności z C99

#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))

#define BUF_1_SIZE 10
#define BUF_2_SIZE 20

//będą wyzerowane przez prolog programu
static char data1[BUF_1_SIZE];
static char data2[BUF_2_SIZE];

//struktura

typedef struct {
    uint8_t index;
    uint16_t counter;
    uint16_t size;
    char * data;
} buffer_t;

//definicja zmiennych

static buffer_t XXX;
static buffer_t YYY;

//funkcje

void buffer_init(buffer_t* buffer, char data_address[], uint16_t size) {
    (*buffer) = (buffer_t) {
        .index = 0,
        .counter = 0,
        .size = size,
        .data = data_address
    };
}

void process_buffer(buffer_t* buffer) {
    // jakiś przykład procesowania...
    switch(buffer->size) {
        case BUF_1_SIZE:
            buffer->data[0] = 'K';
            break;
        case BUF_2_SIZE:
            buffer->data[0] = 'Z';
            break;
    }
}

void show_buffer(buffer_t* buffer) {
    // wyświetlnie bufora...
    printf("Buffer:\nindex = %d\ncounter = %d\ndata = '%s'\nsize = %d\n",
           buffer->index, buffer->counter, buffer->data, buffer->size);
}

int main() {
    //wywolanie
    buffer_init(&XXX, data1, COUNT_OF(data1));
    buffer_init(&YYY, data2, COUNT_OF(data2));
    
    //symulacja obliczeń
    process_buffer(&XXX);
    process_buffer(&YYY);

    //no i co tam w buforze... 
    show_buffer(&XXX);
    show_buffer(&YYY);

    printf("%s, %s\n", data1, data2);

    return EXIT_SUCCESS;
}

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