Undefined function error reference in C

I have created a header file called dm.h that includes all the function prototypes. Then I created a source file called dm.c that includes the source code for all the functions declared in indm.h. After that I started coding in main.c, but when I ran it I got an error: undefined reference to "(function name)". I am getting this error for all my functions.

Below you can find the source code for all of my three files.

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 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;

}

      

If you could help me solve this problem, I would be glad. I think there is some kind of linking issue between my library and the main source file.

Thanks in advance.

+3


source to share


5 answers


I think you are only compiling main.c. You must also include ofdm.c.



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

      

+9


source


Since you are getting this error for all your functions, it cannot be a typo. It is best to assume that you are not linking the two files.

If you are using gcc it is done like this:

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

      



Note, which -c

means it should compile, but not try to create an executable. This means that the connection is not being made.

Once both files are compiled, you link them together.

+3


source


When you learn new things, it helps you learn one new thing at a time. Put your source code in source control, then simplify it to get a clean compiler.

main.c

#include "ofdm.h"

int main(int argc, char *argv[])
{
  return 0;
}

      

ofdm.c

#include "ofdm.h"

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;
  }
}

      

ofdm.h

#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED

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

#endif

      

Then, to compile with gcc.,.

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

      

This should give you a program that does nothing, successfully. You can now start building it again from your version controlled source.

  • Add one function at a time.
  • Edit it to get a clean compiler.
  • Edit this to pass sensible tests.
+2


source


I came here with the same problem when using ESP-IDF as a beginner. What solved it for me is that I just forgot to add all the required sources to the function call idf_component_register

.

0


source


well this cud b bug is easily resolved if u save ur prototype code file in .cpp or .c format and then #include "urfilename.c" then try the program to work well with bt it cud b warning neglected

-1


source







All Articles