Неопределенная ссылка на ошибку 'function' в C - PullRequest
3 голосов
/ 31 марта 2012

Я создал заголовочный файл с именем ofdm.h, который включает в себя все прототипы функций.Затем я создал исходный файл с именем ofdm.c, который включает в себя исходный код всех функций, объявленных в ofdm.h.После этого я начал писать код в main.c, но когда я его запускаю, я получаю ошибку: неопределенная ссылка на '(имя функции)'.Я получаю эту ошибку для всех моих функций.

Ниже вы можете найти исходный код всех моих трех файлов.

ofdm.h

#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED

typedef struct {
    double real, img;
} Complex;

char** split(char *s, const char *delim);
void parseComplex(Complex *c, char *line);

void rbits(short* buf, int nbits);

void printbinary(short* buf, int len);
void printcomplex(Complex* buf, int len);

long bin2dec(short *bin, int len);
void dec2bin(long dec, short *bin, int len);
void binaryadd(short *bin1, short *bin2, short *erg, int len);
void leftshift(short *bin,short *erg,int shifts, int len);
void binarymult(short *bin1, short *bin2, short *erg, int len);
void binarypower(short *bin,short *erg,int power, int len);

void scrambler(short *seed, short *input, short *output, int len, int seedlen);
void encoder(short *input, short *output, int inputlen);

void interleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC);

void fixed_point(short* input, int nbits);
void fixed_point_complex(Complex* input, int nbits);
void defixed_point(short* input, int nbits);

void BPSKmapping(short* input, short* output, int nbits);
void BPSKdemapping(short* input, short* output, int nbits);
void QPSKmapping(short* input, Complex* output, int nbits);
void QPSKdemapping(Complex* input, short* output, int nbits);

void IFFT_BPSK(short* input, Complex* output, Complex* twidder);
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder);

double uniform(double a, double b);
double gauss(double mean, int SNRdb);

void ChannelModel(Complex R[], Complex S[], int SNRdb);

#endif

ofdm.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ofdm.h"

char** split(char* string, const char* delim)
{
    char* p;
    int i = 0;

    char** array = malloc(strlen(string) * sizeof(char*));
    p = strtok(string, delim);

    while(p != NULL)
    {
        array[i] = malloc(sizeof(char));
        array[i++] = p;
        p = strtok(NULL, delim);
    }

    return array;
}

void parseComplex(Complex *cmplx, char *number)
{
    char *copy = number;

    if(strchr(copy, ' ') != NULL)
    {
        char **result = split(copy, " ");
        cmplx->real = atof(*result++);

        char *sign = *result++;
        cmplx->img = atof(*result++);

        if(sign[0] == '-')
            cmplx->img = -(cmplx->img);
    }
    else if(strchr(copy, 'j') != NULL)
    {
        cmplx->real = 0;
        cmplx->img = atof(copy);
    }
    else
    {
        cmplx->real = atof(copy);
        cmplx->img = 0;
    }
}

void rbits(short* buf, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
        buf[i] = (rand() % 2);
}

void printbinary(short* buf, int len)
{
  int i;

  for(i = 0; i < len; i++)
  {
    printf("%d\t", buf[i]);
  }
  printf("\n\n\n");
}

void printcomplex(Complex* buf, int len)
{
    int i;

    for(i = 0; i < len; i++)
    {
        printf("%.0lf %.0lf\t", buf[i].real, buf[i].img);
    }
    printf("\n\n");
}

long bin2dec(short *bin, int len)
{
  long dec = 0;
  int i;

  for(i = 0;i < len;i++)
  {
    dec += bin[i]*pow(2.0,(double) (len - i -1));
  }
  return dec;
}

void dec2bin(long dec, short *bin, int len)
{
  long temp = dec;
  int i;

  for(i = 0;i<len;i++)
  {
    bin[len - 1 - i] = temp % 2;
    temp = temp/2;
  }
}

void binaryadd(short *bin1, short *bin2, short *erg, int len)
{
  int i;
  short carry = 0;
  short oldcarry = 0;
  for(i = len - 1; i >= 0; i--)
  {
    if((bin1[i] + bin2[i] + oldcarry) > 1)
    {
      carry = 1;
    }
    else
    {
      carry = 0;
    }
    erg[i] = (bin1[i] + bin2[i] + oldcarry) % 2;
    oldcarry = carry;
  }
}

void leftshift(short *bin,short *erg,int shifts, int len)
{
  int i;


  for(i = 0;i < len - shifts;i++)
  {
    erg[i] = bin[i + shifts];
  }
  for(i = len - shifts;i < len;i++)
  {
   erg[i] = 0;
  }
}

void binarymult(short *bin1, short *bin2, short *erg, int len)
{
  int i;
  short temp[len - 1];


  for(i = 0;i < len;i++)
  {
   erg[i] = 0;
  }

  for(i = 0;i < len;i++)
  {
    if(bin2[i] == 1)
    {
      leftshift(bin1,temp,len - 1 - i,len);
      binaryadd(temp,erg,erg,len);
    }
  }

}

void binarypower(short *bin,short *erg,int power, int len)
{
  int i;
  short temp[len - 1];

  for(i = 0;i < len;i++)
  {
   temp[i] = 0;
  }
  temp[len - 1] = 1;

  if(power > 1)
    binarypower(bin,temp,power - 1,len);

  binarymult(temp,bin,erg,len);
}


void scrambler(short *seed, short *input, short *output, int len, int seedlen)
{
  int i;
  short carry;
  short sequence[len - 1];
  for(i = 0; i < len; i++)
  {
    sequence[i] = (seed[0] + seed[3]) % 2;
    carry = (seed[0] + seed[3]) % 2;
    leftshift(seed,seed,1,seedlen);
    seed[seedlen - 1] = carry;
    output[i] = (sequence[i] + input[i]) % 2;
  }
}


void encoder(short *input, short *output, int inputlen)
{
  int i;
  short SR[7] = {0,0,0,0,0,0,0};
  short A;
  short B;

  for(i = 0; i < inputlen;i++)
  {
    leftshift(SR,SR,1,7);
    SR[6] = input[i];
    A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) % 2;
    B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) % 2;
    output[2*i] = A;
    output[2*i + 1] = B;
  }
}

/*
void decoder(short *input, short *output, int inputlen)
{
    int i;
    short SR[7] = {0}
    short A;
    short B;
    short C1;
    short C2;

    for(i = 0; i < intputlen; i++)
    {
        leftshift(SR, SR, 1, 7)
        SR[6] = input[i];

        C1 = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) / 2;
        C2 = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) / 2;

        A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) - (2 * C1);
        B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) - (2 * C2);

        output[2*i] = A;     // output[i/2] = A;
        output[2*i + 1] = B; // output[i/2 + 1] = B;
    }
}
*/

void interleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
  int i;
  int t;
  int k;
  int s;
  short first_permutuation[N_CBPS - 1];

  for (k = 0; k < N_CBPS; k++)
  {
    i = (N_CBPS/16)*(k % 16) + (k/16);
    first_permutuation[i] = input[k];
  }

  s = fmax(N_BPSC/2,1);

  for(i = 0; i < N_CBPS;i++)
  {
    t = s*(i/s) + (i + N_CBPS - ((16*i)/N_CBPS)) % s;
    output[t] = first_permutuation[i];
  }
}

void fixed_point(short* input, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
    {
        if(input[i] < 0)
            input[i] *= 32768;
        else input[i] *= 32767;
    }
}

void fixed_point_complex(Complex* input, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
    {
        if(input[i].real == -1 || input[i].img == -1)
            input[i] *= 32768;
        else input[i] *= 32767;
    }
}

void defixed_point(short* input, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
    {
        if(input[i] < 0)
            input[i] /= 32768;
        else input[i] /= 32767;
    }
}

void IFFT_BPSK(short* input, Complex* output, Complex* twidder)
{
    int i, k;

    for(i = 0; i < 64; i++)
    {
        for(k = 0; k < 64; k++)
        {
            output[i].real += (twidder[i][k].real * input[i]) / 64;
            output[i].img += (twidder[i][k].img * input[i]) / 64;
        }
    }
}

void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder)
{
    int i, k;

    for(i = 0; i < 64; i++)
    {
        for(k = 0; k < 64; k++)
        {
            output[i].real += (twidder[i][k].real * input[i].real) / 64;
            output[i].img += (twidder[i][k].img * input[i].img) / 64;
        }
    }
}

void IFFT_QPSK2(Complex* input, Complex* output, Complex* twidder, int nbits)
{
    int a, b, c, d, e, f, g, h, blocks;
    int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
    int next = 0;
    Complex ifft_qpsk_output[64];

    blocks = nbits / 48;

    for(a = 1; a <= blocks; a++)
    {
        // pilots
        output[7].real = 32767;
        output[21].real = 32767;
        output[42].real = 32767;
        output[56].real = -32768;
        // some data
        output[40].real = input[26 + (next * 48)].real;
        output[40].img = input[26 + (next * 48)].img;
        output[41].real = input[27 + (next * 48)].real;
        output[41].img = input[27 + (next * 48)].img;

        // zeroes
        for(b = 28; b <= 39; b++)
            output[b].real = 0;

        // other data
        for(c = 0; c <= 6; c++)
        {
            output[c].real = input[c + (next * 48)].real;
            output[c].img = input[c + (next * 48)].img;
        }


        for(d = 8; d <= 20; d++)
        {
            output[d].real = input[count1++ + (next * 48)].real;
            output[d].img = input[count1++ + (next * 48)].img;
        }


        for(e = 22; e <= 27; e++)
        {
            output[e].real = input[count2++ + (next * 48)].real;
            output[e].img = input[count2++ + (next * 48)].img;
        }


        for(f = 43; f <= 55; f++)
        {
            output[f].real = input[count3++ + (next * 48)].real;
            output[f].img = input[count3++ + (next * 48)].img;
        }


        for(h = 57; h <= 63; h++)
        {
            output[h].real = input[count4++ + (next * 48)].real;
            output[h].img = input[count4++ + (next * 48)].img;
        }


        // IFFT function goes here
        IFFT_QPSK(output, ifft_qpsk_output, twidder);
        printcomplex(ifft_qpsk_output, 64);

        next++;

    }
}

void IFFT_BPSK2(short* input, short* output, Complex* twidder, int nbits)
{
    int a, b, c, d, e, f, g, h, blocks;
    int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
    int next = 0;
    Complex ifft_bpsk_output[64];

    blocks = nbits / 48;

    for(a = 1; a <= blocks; a++)
    {
        // pilots
        output[7] = 32767;
        output[21] = 32767;
        output[42] = 32767;
        output[56] = -32768;
        // some data
        output[40] = input[26 + (next * 48)];
        output[41] = input[27 + (next * 48)];

        // zeroes
        for(b = 28; b <= 39; b++)
            output[b] = 0;

        // other data
        for(c = 0; c <= 6; c++)
            output[c] = input[c + (next * 48)];

        for(d = 8; d <= 20; d++)
            output[d] = input[count1++ + (next * 48)];

        for(e = 22; e <= 27; e++)
            output[e] = input[count2++ + (next * 48)];

        for(f = 43; f <= 55; f++)
            output[f] = input[count3++ + (next * 48)];

        for(h = 57; h <= 63; h++)
            output[h] = input[count4++ + (next * 48)];

        // IFFT function goes here
        IFFT_BPSK(output, ifft_bpsk_output, twidder);
        printcomplex(ifft_bpsk_output, 64);

        next++;

    }
}

void BPSKmapping(short* input, short* output, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
    {
        if(input[i] == 0)
            output[i] = -1;
        else output[i] = 1;
    }
}

void BPSKdemapping(short* input, short* output, int nbits)
{
    int i;

    for(i = 0; i < nbits; i++)
    {
        if(input[i] == -1)
            output[i] == 0;
        else output[i] == 1;
    }
}

void QPSKmapping(short* input, Complex* output, int nbits)
{
    int i;

    for(i = 0; i < nbits; i += 2)
    {
        if(input[i] == 0 && input[i+1] == 0)
        {
            output[i].real = -1;
            output[i+1].img = -1;
        }
        else if(input[i] == 0 && input[i+1] == 1)
        {
            output[i].real = -1;
            output[i+1].img = 1;
        }
        else if(input[i] == 1 && input[i+1] == 0)
        {
            output[i].real = 1;
            output[i+1].img = -1;
        }
        else
        {
            output[i].real = 1;
            output[i+1].img = 1;
        }
    }
}

void QPSKdemapping(Complex* input, short* output, int nbits)
{
    int i;

    for(i = 0; i < nbits; i += 2)
    {
        if(input[i].real == -1 && input[i+1].img == -1)
        {
            output[i] = 0;
            output[i+1] = 0;
        }
        else if(input[i].real == -1 && input[i+1].img == 1)
        {
            output[i] = 0;
            output[i+1] = 1;
        }
        else if(input[i].real == 1 && input[i+1].img == -1)
        {
            output[i] = 1;
            output[i+1] = 0;
        }
        else
        {
            output[i] = 1;
            output[i+1] = 1;
        }
    }
}

//Channel Begin
double uniform(double a, double b)
{
 double c;
 double d;
 static int firstcall = 1;
 c = b - a;
 if(firstcall == 1)
 {
     srand((unsigned int)time(NULL));
     firstcall = 0;
 }

 d = a + (double)rand() / RAND_MAX * c;
 return d;
}

double gauss(double mean, int SNRdb)
{
    double dGaussNum;
    double x = 0;
    int i;
    double sigma;
    sigma = 1 / pow(10, (double)SNRdb / 10);

    for(i = 0;i < 12; i ++)
    {
        x = x + uniform(0,1);
    }
    x = x - 6;
    dGaussNum = mean + sqrt(sigma) * x;
    return dGaussNum;
}

void ChannelModel(Complex R[], Complex S[], int SNRdb)
{
    int i;
    for (i=0;i<N+L;i++)
    {

        R[i].real = S[i].real + gauss(0, SNRdb);
        R[i].img = S[i].img + gauss(0, SNRdb);
    }
}
//Channel End

void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
  int i;
  int t;
  int k;
  int s;
  short first_permutuation[N_CBPS - 1];

  s = fmax(N_BPSC/2,1);

  for (t = 0; t < N_CBPS; t++)
  {
    i = s*(t/s) + (t + ((16*t)/N_CBPS)) % s;
    first_permutuation[i] = input[t];
  }


  for(i = 0; i < N_CBPS;i++)
  {
    k = 16*i - (N_CBPS - 1)*((16*i)/N_CBPS);
    output[k] = first_permutuation[i];
  }
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ofdm.h"

int main(int argc, char *argv[])
{

  short seed[8];
  int bits, i, j, k;
  char mode[5], line[1024];
/*  Complex twidder[64][64];

  FILE *file = fopen("twidder_factor.txt", "r");

  i = 0;
  while(fgets(line, sizeof(line), file ) != NULL)
  {
      k = j = 0;
      char **result = split(line, "\t");

      while(result[k] != NULL)
      {
          parseComplex(&twidder[i][j], result[k++]);
          j++;
      }

      i++;
  }
*/

  printf("How many bits do you want to transmit?: ");
  scanf("%d", &bits);

  short* start_input;
  short* scrambler_output;
  short* encoder_output;
  short* interleaver_output;
  short* bpsk_mapper_output;
  short* ifft_bpsk_input[64];
  Complex* qpsk_mapper_output;
  Complex ifft_qpsk_input[64];

  start_input = malloc(sizeof(short) * bits);

  scrambler_output = malloc(sizeof(short) * bits);

  encoder_output = malloc(sizeof(short) * (bits * 2));

  interleaver_output = malloc(sizeof(short) * (bits * 2));

  bpsk_mapper_output = malloc(sizeof(short) * (bits * 2));

  qpsk_mapper_output = malloc(sizeof(Complex) * (bits * 2));

  if(qpsk_mapper_output == NULL)
  {
      fprintf(stderr, "Couldn't allocate that much memory!\n");
      return 1;
  }

  srand(time(NULL));
  rbits(seed, 8);
  rbits(start_input, bits);

  printf("Which modulation type to you want to use? (type BPSK or QPSK): ");
  scanf("%s", mode);

  if((strcmp(mode, "BPSK") == 0) || (strcmp(mode, "bpsk") == 0))
  {
      printf("\nSelected modulation type: BPSK\n\n\n");
      printf("SCRAMBLER OUTPUT:\n\n");
      scrambler(seed, start_input, scrambler_output, bits, 8);
      printbinary(scrambler_output, bits);

      printf("ENCODER OUTPUT:\n\n");
      encoder(scrambler_output, encoder_output, bits);
      printbinary(encoder_output, bits*2);

      printf("INTERLEAVER OUTPUT:\n\n");
      interleaver(encoder_output, interleaver_output, bits, 1);
      printbinary(interleaver_output, bits*2);

      printf("MAPPER OUTPUT:\n\n");
      BPSKmapping(interleaver_output, bpsk_mapper_output, bits*2);
      printbinary(bpsk_mapper_output, bits*2);

      printf("FIXED-POINT OUTPUT:\n\n");
      fixed_point(bpsk_mapper_output, bits*2);
      printbinary(bpsk_mapper_output, bits*2);
/*
      printf("IFFT OUTPUT:\n\n");
      IFFT_BPSK(bpsk_mapper_output, ifft_bpsk_input, twidder, bits*2)

      defixed_point(bpsk_mapper_output, bits*2);
      printbinary(bpsk_mapper_output, bits*2);
 */ }
  else if((strcmp(mode, "QPSK") == 0) || (strcmp(mode, "qpsk") == 0))
  {
      printf("\nSelected modulation type: QPSK\n\n\n");
      printf("SCRAMBLER OUTPUT:\n\n");
      scrambler(seed, start_input, scrambler_output, bits, 8);
      printbinary(scrambler_output, bits);

      printf("ENCODER OUTPUT:\n\n");
      encoder(scrambler_output, encoder_output, bits);
      printbinary(encoder_output, bits*2);

      printf("INTERLEAVER OUTPUT:\n\n");
      interleaver(encoder_output, interleaver_output, bits, 2);
      printbinary(interleaver_output, bits*2);

      printf("MAPPER OUTPUT:\n\n");
      QPSKmapping(interleaver_output, qpsk_mapper_output, bits*2);
      printcomplex(qpsk_mapper_output, bits*2);
/*
      printf("FIXED-POINT OUTPUT:\n\n");
      fixed_point_complex(qpsk_mapper_output, bits*2);
      printcomplex(qpsk_mapper_output, bits*2);

      printf("IFFT OUTPUT:\n\n");
      IFFT_QPSK(qpsk_mapper_output, ifft_qpsk_input, twidder, bits*2)

      defixed_point(qpsk_mapper_output, bits*2);
      printbinary(qpsk_mapper_output, bits*2);
*/  }
  else
  {
      printf("That's an invalid modulation type!\n");
      free(start_input);
      free(scrambler_output);
      free(encoder_output);
      free(interleaver_output);
      free(bpsk_mapper_output);
      free(qpsk_mapper_output);
      return 0;
  }


  free(start_input);
  free(scrambler_output);
  free(encoder_output);
  free(interleaver_output);
  free(bpsk_mapper_output);
  free(qpsk_mapper_output);

  system("PAUSE");

  return 0;

}

Если бы вы могли помочь мне решить эту проблему, я был быРады.Я думаю, что есть какая-то проблема со связью между моей библиотекой и основным исходным файлом.

Заранее спасибо.

Ответы [ 4 ]

9 голосов
/ 31 марта 2012

Полагаю, вы компилируете только main.c. Вы также должны включить ofdm.c.

$ gcc -Wall main.c ofdm.c -o output
3 голосов
/ 31 марта 2012

Поскольку вы получаете эту ошибку для всех ваших функций, она не может быть опечаткой.Я думаю, вы не связываете эти два файла.

Если вы используете gcc, это делается следующим образом:

gcc -o main.o -c main.c
gcc -o ofdm.o -c ofdm.c
gcc -o program main.o ofdm.o

Обратите внимание, что -c означает, что он должен скомпилироваться,но не пытайтесь создать исполняемый файл.Это означает, что связывание не выполнено.

Как только оба файла скомпилированы, вы можете связать их вместе.

2 голосов
/ 31 марта 2012

Когда вы изучаете новые вещи, это помогает изучать одну новую вещь за один раз.Поместите ваш исходный код в систему управления версиями, а затем упростите ее, чтобы получить чистую компиляцию.

#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED

void leftshift(short *bin,short *erg,int shifts, int len);

#endif

Затем скомпилировать с gcc.,.

$ gcc -Wall -c ofdm.c
$ gcc -Wall -c main.c
$ gcc -Wall *.o

Это должно дать вам программу, которая ничего не делает, успешно.Теперь вы можете начать сборку заново из вашего источника, управляемого версиями.

  • Добавляйте по одной функции за раз.
  • Отредактируйте ее, чтобы получить чистую компиляцию.
  • Отредактируйте ее, чтобы пройти нормальные тесты.
0 голосов
/ 31 марта 2012

эта ошибка программы легко решается, если вы сохраните файл кода функции прототипа в формате .cpp или .c, а затем упомяните #include "urfilename.c", а затем попытаетесь, чтобы программа работала хорошо с предупреждением об этом. cud b пренебрег

...