Hello everyone. Its been a while since I posted. I've gone through many threads regarding Linking issues that beginning programmers come across. Its the linking error - "error LNK2001 : unresolved external symbol." I admit I am a beginner and I also encounter the same problem. Going through all of the threads I became even more confused. I found no explicit details and the textbooks doesn't cover much of it either. Point is, I came up with a check list, my memory isn't as spiffy as it used to be so I hope that someone can confirm if I have it all correctly stated.
I use a Software Development Kit VC++6 Enterprise version ice-age.

1. I created a blank workspace and added an empty WIN32 windows application project.

2. I immediately go to Menu-Tool-Option and add all the includes, libs, and resources under the directories tab.

3. I then proceed to the coding and organized it as follows:

  • Placed the Class definitions in their respective source files
  • Placed the Class constructs in their respective header files
  • Created a header containment Header file that lists all include directives and any other pre-process directives
  • Create a source file that contains the WinMain and WindowProcedure functions

In the example below it demonstrate what I do in my projects-
I created a total of five files. 3 headers and 2 sources.

Headers:

  • Engine.h
  • HeaderIncludes.h
  • Main.h

Sources:

  • Engine.cpp
  • Main.cpp

In Engine.h-

#include "HeaderIncludes.h"

In Main.h-

#pragma once // Just in case it gets called twice somehow
#include "HeaderIncludes.h"
#include "Engine.h"

In HeaderInclude.h-

#include <windows.h>
#include <windowsx.h>

In Main.cpp-

#include "Main.h"
#include "Engine.h'

In Engine.cpp-

#include "Engine.h"

Sorry, if it gets really long. HMMM, what do you guys think? Is it correct or am I forgetting some steps? Because I wanted to make sure that I'm doing it correctly so I don't get those linking errors ever again and as to boost my morale as a new programmer. Thank you all so very much in advance.

Recommended Answers

All 2 Replies

That kind of error usually means you've missed out a definition somewhere - For example, if you've declared something in a header file, such as a function. Elsewhere in your code, you may have called that function, and the linker is unable to find the implementation to go with it.

Without seeing the code which exhibits the problem, there's no way to give any more information than that.

Yes, you are absolutely correct Sir Bench. I did forget to declare a variable. I commend your brilliance with sound applaud. You are in concurrence to my checklist? Bravo, I knew I forgot something as so important as the dear variable itself. I have posted the code and indicated where I had forgotten. Oh and I posted another thread called, "Is there a way to end forever loops?" If you are interested in this thread please feel free. I am quite alright with sharing any of my codes. The rest are not really necessary but provides and idea of my setups. I made the WinMain and WindowProc as part of my class library. I still have to master manually creating a makefile, a dll and a def file. Although, I heard rumors that I would need to get an executable that will allow me to do so.

In Engine.cpp:

#include "New01Main.h"

/*****************************************/
RPGEngine *RPGEngine::cm_pEngine = NULL;     // This is where I forgot to declare the variable
/*****************************************/

LRESULT CALLBACK t1f_winprocedure(HWND hwnd, UINT umsg, WPARAM upperparam, LPARAM lowerparam)
{
  return RPGEngine::ReleaseEngine()->cf_winproc(hwnd, umsg, upperparam, lowerparam);
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevi, LPTSTR szcmdline, int ishow)
{
  MSG msg;
  static int iTrigger = 0;

  if(AppInit(hinst))
  {
    if(!RPGEngine::ReleaseEngine()->InitMech(ishow))
    {
      return false;
    }

    while(true)
    {
      if(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
      {
        if(msg.message == WM_QUIT)
        {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
          break;
        }
      }
      else
      {
        AppIterate();
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    }//Close while
    //return (int)msg.wParam;
    return (int)msg.wParam;
  }//Close primary if statement
  //Support function
  AppEnd();
  return true;
}//Close WinMain

//The constructor
RPGEngine::RPGEngine(HINSTANCE hinst, LPTSTR classname, LPTSTR classtitle, WORD wicon, WORD wiconsm, int iwidth, int iheight)
{
  cm_pEngine  = this;//&cm_oEngine;
  cm_hinst    = hinst;
  cm_hwnd     = NULL;

  //If there is a text string in the name copy it into class member
  if(lstrlen(classname)>0)
  {
    lstrcpy(cm_classname, classname);
  }

  //If there is a text string in the title copy it into the class member
  if(lstrlen(classtitle)>0)
  {
    lstrcpy(cm_classtitle, classtitle);
  }

  cm_wicon    = wicon;
  cm_wiconsm  = wiconsm;
  cm_iwidth   = iwidth;
  cm_iheight  = iheight;
}

//The destructor
RPGEngine::~RPGEngine()
{
}

bool RPGEngine::InitMech(int ishow)
{
  wcx.cbSize = sizeof(wcx);
  wcx.style = CS_HREDRAW | CS_VREDRAW;
  wcx.lpfnWndProc = t1f_winprocedure;
  wcx.cbClsExtra = 0;
  wcx.cbWndExtra = 0;
  wcx.hInstance = cm_hinst;
  wcx.hIcon = LoadIcon(cm_hinst, MAKEINTRESOURCE(LeakIcon()));
  wcx.hIconSm = LoadIcon(cm_hinst, MAKEINTRESOURCE(LeakIconSm()));
  wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wcx.lpszMenuName = NULL;
  wcx.lpszClassName = cm_classname;

  //If register fails exit
  if(!RegisterClassEx(&wcx))
  {
    return false;
  }

  int iWindowWidth = cm_iwidth + GetSystemMetrics(SM_CXFIXEDFRAME)*2, iWindowHeight = cm_iheight + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);

  if(wcx.lpszMenuName != NULL)
  {
    iWindowHeight += GetSystemMetrics(SM_CYMENU);
  }

  int iXWindowPos = (GetSystemMetrics(SM_CXSCREEN) - iWindowWidth)/2, iYWindowPos = (GetSystemMetrics(SM_CYSCREEN) - iWindowHeight)/2;

  cm_hwnd = CreateWindow(cm_classname, cm_classtitle, WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX, iXWindowPos, iYWindowPos, iWindowWidth, iWindowHeight, NULL, NULL, cm_hinst, NULL);

  if(!cm_hwnd)
  {
    return false;
  }

  ShowWindow(cm_hwnd, ishow);
  UpdateWindow(cm_hwnd);

  return true;
}

LRESULT CALLBACK RPGEngine::cf_winproc(HWND hwnd, UINT umsg, WPARAM upperparam, LPARAM lowerparam)
{
  switch(umsg)
  {
    case WM_CREATE:
      SetWindow(hwnd);
      //Support function
      AppStart(hwnd);
      return 0;

    case WM_ACTIVATE:
      if(upperparam != WA_INACTIVE)
        {
          return 0;
        }

    case WM_PAINT:
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint(hwnd, &ps);

      //Support function
      AppPaint(hdc);

      EndPaint(hwnd, &ps);
      return 0;

    case WM_DESTROY:
      //Support function
      AppEnd();
      PostQuitMessage(0);
      return 0;
  }
  return DefWindowProc(hwnd, umsg, upperparam, lowerparam);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.