Linking 2 files using extern in C

Link 2 files using an extern command in linux? (with a makefile)

Page 1 of 1

1 Replies - 1909 Views - Last Post: 20 April 2010 - 04:41 AM Rate Topic: -----

#1 Guest_Cloudyeyes*


Reputation:

Linking 2 files using extern in C

Posted 19 April 2010 - 11:51 PM

How would I link 2 files together using an external function? I downloaded Dev-C++ so I could create a makefile in a Windows environment, but I keep getting an error saying "[Linker error] undefined reference to CalculateTotalsAndNetPay."

What I need to do is link an external function to my main source code in C, which works in a Linux environment. My professor hasn't been accepting any of my assignments because I don't know how to do this (even though my programs do work in windows, but I don't have a makefile). I'm a total newbie to Linux and have been trying to figure this out for the past month...

Problem code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

        extern "C" void CalculateTaxesAndNetPay(float *fedtax, float gross, float deferred, float *statetax, float *ssitax, float *netpay);

int main()
{
CalculateTaxesAndNetPay(&fedtax, gross, deferred, &statetax, &ssitax, &netpay);

        fflush(stdin);
        getchar();
        return 0;
}



Problem external function: (named calculatetotalsandnetpay.cpp)
		void CalculateTaxesAndNetPay(float *fedtax, float gross, float deferred,
                float *statetax, float *ssitax, float *netpay) //calculates all taxes and net
        {
                
                *fedtax = 15 * ((gross - deferred)/100); 
                *statetax = 7 * ((*fedtax)/100);
                *ssitax = 7.75*((gross - deferred)/100);
                *netpay = gross - *fedtax - *statetax - *ssitax - deferred;
        }


Full source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

	//  NAME  : Brian Bennett
	//  CLASS : CISP 360, Wednesday 7pm
	//  PROGRAM TITLE : Lab assignment 2: Calculate Payroll
    //  Purpose: To print a report of all employee data
    //  Software Change(Modifications) Record
    //  date         what              who
    //  3/23/2010    Created file      Dixon

//prints the report headers
        void PrintReportHeadings(FILE *reportfile) 
        {
        fprintf(reportfile,"       Employee                Pay Rate     Reg Hrs      Tot Gross Pay   Fed Tax \n");
        fprintf(reportfile,"       Name                    SSI Tax      Reg Gross    Tot Net Pay     State Tax \n");
        fprintf(reportfile,"                               Defr Amt     Ovt Hrs                      \n");
        fprintf(reportfile,"                                            Ovt Gross                    \n");
        fprintf(reportfile,"       ====================    ========     =========    =============   ========= \n");
        fprintf(reportfile,"                               ========     =========    \n");
        }

//user input for an employee's data, then converts the full name into a string.
        void InputEmployeeData(char *firstname, char *lastname, char *combinenames,
			float *hours, float *payrate, float *deferred)
        {
                printf("Full employee name: \n");
                scanf("%s %s", firstname, lastname);
                printf("Hours, payrate, deferred (use a space between each value): \n");
                scanf("%f %f %f", hours, payrate, deferred);
                strcpy(combinenames,lastname);  
                strcat(combinenames,", ");
                strcat(combinenames,firstname);
        }

//separates regular hours from overtime hours and calculates each, as needed
        void CalculateHoursAndWage(float *gross, float payrate, float hours,
                float *reggross, float *reghrs, float *ovtgross, float *ovthrs) 
        {
        if (hours <=40) {
                *reghrs = hours;
                *ovthrs = 0;
                *ovtgross = 0;
        } else {
                *reghrs = 40;
                *ovthrs = hours - *reghrs;
                *ovtgross = (hours - *reghrs) * (1.5 * payrate);
        }
        *reggross = *reghrs * payrate;
        *gross = *reggross + *ovtgross;
        }

//pulling an external function from calculatetaxesandnetpay (which calculates taxes and net)
        extern "C" void CalculateTaxesAndNetPay(float *fedtax, float gross, float deferred,
                float *statetax, float *ssitax, float *netpay); //calculates all taxes and net
                
//adds up the totals from each employee
        void CalculateTotals(float *totpayrate, float *totreghrs, float *totgross, float *totfedtax,
                 float *totssitax, float *totreggross, float *totdeferred, float *totovthrs,
				 float *totnetpay, float *totstatetax, float *totovtgross, float payrate,
				 float reghrs, float gross, float fedtax, float ssitax, float reggross,
				 float deferred, float ovthrs, float netpay, float statetax, float ovtgross)
        {
                *totpayrate = *totpayrate + payrate;
                *totreghrs = *totreghrs + reghrs;
                *totgross = *totgross + gross;
                *totfedtax = *totfedtax + fedtax;
                *totssitax = *totssitax + ssitax;
                *totreggross = *totreggross + reggross;
                *totdeferred = *totdeferred + deferred;
                *totovthrs = *totovthrs + ovthrs;
                *totnetpay = *totnetpay + netpay;
                *totstatetax = *totstatetax + statetax;
                *totovtgross = *totovtgross + ovtgross;
        }

//prints out each individual's full data
        void PrintEmployeeData(char *combinenames, FILE *reportfile, float payrate, float reghrs,
			float gross, float fedtax, float ssitax, float reggross, float netpay, float statetax,
			float deferred, float ovthrs, float ovtgross, char empty)
        {
                fprintf(reportfile,"\n");  
                fprintf(reportfile,"       %20s%12.2f%14.2f%17.2f%12.2f \n",
                         combinenames, payrate, reghrs, gross, fedtax);
                fprintf(reportfile,"                           %12.2f%14.2f%17.2f%12.2f \n", ssitax,
					reggross, netpay, statetax);
                fprintf(reportfile,"                           %12.2f%14.2f \n", deferred, ovthrs);
                fprintf(reportfile,"                           %12c%14.2f \n", empty, ovtgross);
                fprintf(reportfile,"\n");
        }

//calculates all total averages
        void CalculateAverages(int numemps, float *avpayrate, float *avreghrs, float *avgross,
			float *avfedtax, float *avssitax, float *avreggross, float *avdeferred, float *avovthrs,
			float *avnetpay, float *avstatetax, float *avovtgross, float totpayrate, float totreghrs,
			float totgross, float totfedtax, float totssitax, float totreggross, float totdeferred,
			float totovthrs, float totnetpay, float totstatetax, float totovtgross)
        {               
                *avpayrate = (totpayrate)/(numemps);
                *avreghrs = (totreghrs)/(numemps);
                *avgross = (totgross)/(numemps);
                *avfedtax = (totfedtax)/(numemps);
                *avssitax = (totssitax)/(numemps);
                *avreggross = (totreggross)/(numemps);
                *avdeferred = (totdeferred)/(numemps);
                *avovthrs = (totovthrs)/(numemps);
                *avnetpay = (totnetpay)/(numemps);
                *avstatetax = (totstatetax)/(numemps);
                *avovtgross = (totovtgross)/(numemps);
        }
//prints out all the accumulators, such as total averages and totals for each category
        void PrintAccumulators(FILE *reportfile,float totpayrate,float totreghrs,float totgross,
                float totfedtax,float totssitax,float totreggross,float totnetpay,float totstatetax,
				float totdeferred,float totovthrs,float totovtgross,float avpayrate,float avreghrs,
				float avgross,float avfedtax,float avssitax,float avreggross,float avnetpay,
				float avstatetax,float avdeferred,float avovthrs,float avovtgross,char empty)
        {
        fprintf(reportfile,"Totals %20c%12.2f%14.2f%17.2f%12.2f \n",
                         empty, totpayrate, totreghrs, totgross, totfedtax);
        fprintf(reportfile,"                           %12.2f%14.2f%17.2f%12.2f \n", totssitax,
			totreggross, totnetpay, totstatetax);
        fprintf(reportfile,"                           %12.2f%14.2f \n", totdeferred, totovthrs);
        fprintf(reportfile,"                           %12c%14.2f \n", empty, totovtgross);
        fprintf(reportfile,"\n");
        fprintf(reportfile,"Averages%19c%12.2f%14.2f%17.2f%12.2f \n",
                         empty, avpayrate, avreghrs, avgross, avfedtax);
        fprintf(reportfile,"                           %12.2f%14.2f%17.2f%12.2f \n", avssitax,
			avreggross, avnetpay, avstatetax);
        fprintf(reportfile,"                           %12.2f%14.2f \n", avdeferred, avovthrs);
        fprintf(reportfile,"                           %12c%14.2f \n", empty, avovtgross);
        }

int main()
{
        FILE *reportfile;
        reportfile = fopen("reportfile.txt", "w");
                if (reportfile != NULL) //opens file and checks for open error
                {
                char  lastname[9], firstname[9], combinenames[20], empty=' '; //initialize all variables
                float hours=0, payrate=0, deferred=0, gross=0, fedtax=0, statetax=0,
                        ssitax=0, ovthrs=0, reghrs=0, ovtgross=0, netpay=0, reggross=0,
                        totpayrate=0, totreghrs=0, totgross=0, totfedtax=0, totssitax=0,
                        totreggross=0, totdeferred=0, totovthrs=0, totnetpay=0, totstatetax=0, totovtgross=0, 
                        avpayrate=0, avreghrs=0, avgross=0, avfedtax=0, avssitax=0, avreggross=0,
                        avdeferred=0, avovthrs=0, avnetpay=0, avstatetax=0, avovtgross=0;
                int i=0, numemps=0;
                PrintReportHeadings(reportfile);
        printf("How many employees do you wish to enter? ");
        scanf("%d", &numemps); //user input for amount of employees
                while(i < numemps) //loops each employee's data, calculations and prints their data
        {
                InputEmployeeData(&firstname[0], &lastname[0], &combinenames[0], &hours, &payrate, &deferred);
                CalculateHoursAndWage(&gross, payrate, hours, &reggross, &reghrs, &ovtgross, &ovthrs);
                CalculateTaxesAndNetPay(&fedtax, gross, deferred, &statetax, &ssitax, &netpay);
                CalculateTotals(&totpayrate, &totreghrs, &totgross, &totfedtax, &totssitax, &totreggross, 
                    &totdeferred, &totovthrs, &totnetpay, &totstatetax, &totovtgross, payrate, reghrs, gross
                    , fedtax, ssitax, reggross, deferred, ovthrs, netpay, statetax, ovtgross);
                PrintEmployeeData(&combinenames[0], reportfile, payrate, reghrs, gross, fedtax
                    , ssitax, reggross, netpay, statetax, deferred, ovthrs, ovtgross, empty);
                hours=0, payrate=0, deferred=0, reghrs=0, ovthrs=0;
                i++;
        }
                CalculateAverages(numemps, &avpayrate, &avreghrs, &avgross, &avfedtax, &avssitax, 
                    &avreggross, &avdeferred, &avovthrs, &avnetpay, &avstatetax, &avovtgross, 
                    totpayrate, totreghrs, totgross, totfedtax, totssitax, totreggross, 
                    totdeferred, totovthrs, totnetpay, totstatetax, totovtgross);
                PrintAccumulators(reportfile, totpayrate, totreghrs, totgross,
                    totfedtax, totssitax, totreggross, totnetpay, totstatetax, totdeferred, totovthrs,
                    totovtgross, avpayrate, avreghrs, avgross, avfedtax, avssitax, avreggross,
                    avnetpay, avstatetax, avdeferred, avovthrs, avovtgross, empty);
                } else {
                printf("Unable to open file.\n"); //if open error, "Unable to open file.
        }
        fflush(stdin);
        getchar();
        return 0;
}



Is This A Good Question/Topic? 0

Replies To: Linking 2 files using extern in C

#2 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5760
  • View blog
  • Posts: 12,574
  • Joined: 16-October 07

Re: Linking 2 files using extern in C

Posted 20 April 2010 - 04:41 AM

While I applaud your lack of globals; great crap, man, that's a lot of variables. Consider a struct, or five.

First, you don't need the extern "C" thing. It's actually only valid in C++. You can use a forward declaration if it makes you feel better. Just "void CalculateTaxesAndNetPay...", but it shouldn't matter. The extern keyword in C is implicit unless you turn it off. Something declared static will not be extern.

The accepted way to have one .c file use functions in another is to have that other declare a header file. While this is preferred, it's not required. All that you need to do is compile all your .c files as "object code" files, then link everything together at the end. The linking process looks for non local declarations in the other object files.

Rather than mess with your monster, here's a simple example.

main.c:
#include <stdio.h>

int main() {
	int n = calc(2, 2);
	printf("%d\n", n);
	return 0;
}



func.c:
#include <stdio.h>

int calc(int n1, int n2) {
	printf("called: calc(%d, %d)\n", n1, n2);
	return n1+n2;
}



Command Line:
baavgai@dic:~/C$ gcc -c main.c
baavgai@dic:~/C$ gcc -c func.c
baavgai@dic:~/C$ gcc -o test main.o func.o
baavgai@dic:~/C$ ./test 
called: calc(2, 2)
4
baavgai@dic:~/C$ 



Hope this helps.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1