1

Previously I am able to get the result, but took it further to broaden my understanding its workings.

Unit1.h

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
TButton *Button1;
TButton *Button2;
TLabel *Label1;
TLabel *Label2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "unit2.h"
#include "Unit3.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

int lengthOfYard;
int widthOfYard;
int areaOfYard;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2 = new TForm2(this);
widthOfYard = getWidth();
lengthOfYard = getLength();
//widthOfYard = 15;
//lengthOfYard = 17;
Form2->ShowModal();
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
areaOfYard= FindArea(lengthOfYard,widthOfYard);
Label2->Caption = "\nYour yard is "+ String(areaOfYard) +" square feet\n\n";
}

//---------------------------------------------------------------------------

unit2.h

//---------------------------------------------------------------------------

#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:    // IDE-managed Components
private:    // User declarations
public:     // User declarations
    __fastcall TForm2(TComponent* Owner);
    int getLength();
    int getWidth();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif

unit2.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;

//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

int getLength()
{
    return 15;
}

//---------------------------------------------------------------------------

int getWidth()
{
    return 17;
}

//---------------------------------------------------------------------------

Unit3.h

//---------------------------------------------------------------------------
#ifndef Unit3H
#define Unit3H
//---------------------------------------------------------------------------

// declare the function here in the header file.

int FindArea(int length, int width); //function prototype

#endif//--------------------------------------------------------------------    -------

unit3.cpp

//---------------------------------------------------------------------------

#pragma hdrstop

#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

int FindArea(int l, int w)
{
    return l * w;
}

I got the error like

[bcc32 Error] Unit1.cpp(31): E2268 Call to undefined function 'getLength'

and

[bcc32 Error] Unit1.cpp(32): E2268 Call to undefined function 'getWidth'

I cannot figure it as I compared these new functions' declarations and definitions with "FindArea" function.

manlio
  • 18,345
  • 14
  • 76
  • 126
user1739825
  • 820
  • 4
  • 10
  • 27
  • This question is quite unclear to me, the error messages otoh quite clear IMHO. You really should explain better what you try to do, what was working, what you expect to see, what you changed and, what you then exect to see and what you actually see. – planetmaker Jun 26 '15 at 07:55
  • When I compile the error, the error pop up just as you had seen those errors mentioned above. What i had changed/added is that I created functions in Unit2 so that they are called from Unit1. For further deails, the errors showed "[bcc32 Error] Unit1.cpp(31): E2268 Call to undefined function 'getWidth' Full parser context Unit1.cpp(28): parsing: void _fastcall TForm1::Button1Click(TObject *) [bcc32 Error] Unit1.cpp(32): E2268 Call to undefined function 'getLength' Full parser context Unit1.cpp(28): parsing: void _fastcall TForm1::Button1Click(TObject *)". – user1739825 Jun 26 '15 at 08:15
  • Just realised that I had left out some code that led to confusion. I apologised. I had just updated it. – user1739825 Jun 26 '15 at 08:29

1 Answers1

0

You're calling getLength() and getWidth() from within Unit1.cpp.

In that translation unit, these two functions aren't visible ("they're in" Unit2.cpp. Take a look at What is external linkage and internal linkage?).

You have two options:

  • add

    extern int getLength();
    extern int getWidth();
    

    at the beginning of Unit1.cpp file. The extern keyword indicates external linkage (i.e. the definition of the function may be expected to come from some other C++ file). The compiler will trust that you have implemented the function somewhere. If the linker cannot find it, you will get a linker error.

  • declare the two functions in Unit2.h and include this header file in Unit1.cpp (for further details: C++ extern keyword on functions. Why no just include the header file?).

BUT

you should note that your getLength() function isn't the implementation of the TForm2::getLength() member function.

To define TForm2::getLength() you have to write:

int TForm2::getLength()
{
  return 15;
}

(you should also include Unit2.h inside Unit1.cpp)

The syntax to call TForm2::getLength() is:

Form2->getLength()

Usually a member function that doesn't access private/protected data members doesn't make much sense (you should prefer a free function).

Community
  • 1
  • 1
manlio
  • 18,345
  • 14
  • 76
  • 126
  • Interesting... I did not know that there more new things to learn. it seems that the method of coding is somewhat different for both form unit and non-form unit. ... – user1739825 Jun 26 '15 at 09:30
  • Your first option is not really an option. Yes it compiles, but it is a bad idea because it makes it easy for you to make a mistake and introduce undefined behaviour with no diagnostic (e.g. if you wrote `extern double getWidth();` by mistake). The proper way to organize free functions is that *one* header should have the function declaration; and any code which needs to call that function should include that header. – M.M Jun 29 '15 at 10:40
  • @MattMcNabb It could be useful for a quick-fix/test but of course the correct, DRY organization is based on include files (as can also be inferred by the linked answers). Anyway I thought it was important to list both "options" since both can help to understand the underlying concepts. – manlio Jun 29 '15 at 11:05