Я получаю ошибку компиляции при попытке компилировать мой код - PullRequest
0 голосов
/ 18 апреля 2019

Я создаю программу для своего семестрового проекта, которая берет растровое изображение в формате .pbm, упрощает его с помощью кривых Безье и выводит результат в формате .eps.Университет предложил, чтобы мы работали над проектом с массивами переменного размера, и уже дал объявления.

Структура для массива переменного размера квадратичных Безье:

typedef struct TTV_Bezier2_
{
  UINT nb;
  UINT cap;
  UINT taille_elt;
  Bezier2 * tab;
}TTV_Bezier2;

UINT являетсяобъявление, данное от университета (typedef unsigned int) Bezier2 - это тип, созданный мной.Это репрезентация квадратичного Безье в моей программе, определяемая его 3 контрольными точками:

typedef struct Bezier_q
{
    Point C0;
    Point C1;
    Point C2;
}Bezier2;

Точка - это другая структура typedef:

typedef struct Point_ {
    double x,y;
} Point;

Вот моя проблема: массив переменного размераБезье определяется внутри файла с именем TTV_Bezier.h, а тип Безье2 определяется внутри файла с именем bezier.h.Я включил файлы друг в друга, потому что каждый файл использует эти типы из другого.Однако при компиляции я получаю следующую ошибку:

gcc -c -g -O2 -Wall -I. test_simplification_bezier2.c

In file included from TTV_Bezier2.h:8,
  from test_simplification_bezier2.c:8:
  bezier.h:91:1: error: unknown type name ‘TTV_Bezier2’; did you mean ‘Bezier2’?
  TTV_Bezier2 * simplification_douglas_peucker_bezier2(TTV_Point CONT, int j1, int j2, double d);

Мне сказали, что есть проблема с моими зависимостями внутри Makefile, но я так не думаю, потому что я уже включилих к нужным файлам.Не могли бы вы мне помочь?

Файлы:

TTV_Bezier2.h:

#ifndef _TTV_BEZIER2_H_
#define _TTV_BEZIER2_H_

#include <stdio.h>
#include <stdlib.h>

#include "types_macros.h"
#include "bezier.h"

typedef struct TTV_Bezier2_
{
    UINT nb;
    UINT cap;
    UINT taille_elt;
    Bezier2 * tab;
}TTV_Bezier2;

TTV_Bezier2 * creer_TTV_Bezier2_vide();

Bezier2 element_TTV_Bezier2(TTV_Bezier2 T, UINT i);

UINT nb_elements_TTV_Bezier2(TTV_Bezier2 * T);

TTV_Bezier2 * ajouter_element_TTV_Bezier2(TTV_Bezier2 * T, Bezier2 e);

TTV_Bezier2 * concatener_TTV_Bezier2(TTV_Bezier2 * T1, TTV_Bezier2 * T2);

void supprimer_TTV_Bezier2(TTV_Bezier2 *ptr_T);

#endif

bezier.h:

#ifndef _BEZIER_H_
#define _BEZIER_H_

#include "TTV_Bezier2.h"
#include "TTV_Point.h"
#include "geom2d.h"

//Definition du type Bezier2
typedef struct Bezier_q
{
    Point C0;
    Point C1;
    Point C2;
}Bezier2;

//Definition du type Bezier3
typedef struct Bezier_s
{
    Point C0;
    Point C1;
    Point C2;
    Point C3;
}Bezier3;

//Fonction qui calcule le point de la Bezier quadratique C(t) au parametre t
Point calculate_bezier_2(Bezier2 b, double t);

//Fonction qui calcule le point de la Bezier cubique C(t) au parametre t
Point calculate_bezier_3(Bezier3 b, double t);

//Fonction qui calcule la distance entre un point et une bezier quadratique
double distance_point_bezier2(Point P, Bezier2 B, double t);

//Fonction qui calcule la distance entre un point et une bezier cubique
double distance_point_bezier3(Point P, Bezier3 B, double t);

//Fonction qui calcule le factoriel d'un nombre
double factorial (int i);

//Fonction qui prend une Bezier quadratique et la transforme en Bezier cubique
Bezier3 convert_bezier2_to_3(Bezier2 b);

//Fonction qui calcule la base bernstein B(i,d,t)
double calculate_bernstein_base(int i, int d, double t);

//Fonction qui calcule γ(k)
double calculate_gamma(int i, int n);

//Fonction qui approxime la sequence de points CONT par une Bezier quadratique
Bezier2 approx_bezier2(Point * tab, int j1, int j2);

//Fonction qui approxime la sequence de points CONT par une Bezier cubique
Bezier3 approx_bezier3(Point * tab, int j1, int j2);

//Fonction qui simplifie le contour avec une Bezier cubique
Bezier3_t * simplification_douglas_peucker_bezier3(Point * CONT, int j1, int j2, double d);

//Fonction qui simplifie le contour avec une Bezier quadratique
TTV_Bezier2 * simplification_douglas_peucker_bezier2(TTV_Point CONT, int j1, int j2, double d);

#endif /* _BEZIER_H_ */

test_simplification_bezier2.c:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "image_pbm.h"
#include "geom2d.h"
#include "TTV_Point.h"
#include "TTV_Bezier2.h"
#include "calcul_contours_multiples.h"

int main(int argc, char * argv[])
{
    if (argc != 4)
    {
        printf("Usage: ./test_simplification_bezier <source.pbm> <destination.eps> <distance_seuil>\n");
        return 0;
    }

    FILE * f;
    double distance_seuil;
    int i = 0;
    Image M, P;
    Point init;
    TTV_Point contour;
    TTV_Bezier2 * L;

    L = creer_TTV_Bezier2_vide();
    contour = creer_TTV_Point_vide();

    f = fopen(argv[2], "w");
    distance_seuil = atof(argv[3]);

    //Lecture de l'image
    M = lire_fichier_image(argv[1]);

    //Creation de l'image masque
    P = create_mask_image(M);

    fprintf(f, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n0 setlinewidth\n", M.L, M.H);
    while(is_empty(P) == -1)
    {
        init = trouver_point_init(P);
        contour = trouver_pixel_depart_TTV(M,P,init);
        while(i < nb_elements_TTV_Point(contour))
        {
            contour.tab[i].y = fabs((double) M.H - contour.tab[i].y);
            i++;
        }
        i = 0;
        L = simplification_douglas_peucker_bezier2(contour, 0, nb_elements_TTV_Point(contour) - 1, distance_seuil);
        write_to_file_bezier2(L,f);
    }
    fprintf(f, "\nfill\nshowpage");
    fclose(f);
    return 0;
}

Ответы [ 2 ]

2 голосов
/ 18 апреля 2019

в TTV_Bezier2.h вы включаете bezier.h и в bezier.h вы включаете TTV_Bezier2.h, это источник вашей проблемы

но в bezier.h вам не нужно знать точное определение TTV_Bezier2, поскольку вы ссылаетесь на него только через указатель, поэтому в bezier.h :

  • удалить #include "TTV_Bezier2.h"
  • добавить struct TTV_Bezier2_;
  • заменить тип возврата simplification_douglas_peucker_bezier2 на struct TTV_Bezier2_ *

И добавьте #include "TTV_Bezier2.h" в источники при необходимости

1 голос
/ 18 апреля 2019

У вас есть круговая зависимость между bezier.h и TTV_Bezier2.h

Если вы думаете о функции препроцессора #include, как о простом сведении исходного кода в один гигантский файл для компилятора, начиная с main.c:

  • main включает (среди прочего) TTV_Bezier.h
  • TTV_Bezier.h включает bezier.h перед определением или объявлением TTV_Bezier2
  • bezier.h будет включатьTTV_Bezier.h, но он не будет работать из-за включенных защитных элементов (и это хорошо)

Если вы представляете себе сплющенный вывод препроцессора в памяти компилятора, содержимое bezier.hпредставьте перед любым упоминанием TTV_Bezier, так что вы получите сообщение об ошибке.

Чтобы исправить это, вы можете:

  • Переместить прототип TTV_Bezier2 * simplification_douglas_peucker_bezier2 в TTV_Bezier2.h
  • ИЛИ Переместите структуры, которые необходимы для обоих заголовков, в новый третий заголовок и включите его в оба.
  • или сделайте то, что есть в ответе Бруно и прямом объявлениие структура
...