I developed two classes for running a camera frame grabber in a console app (one to grab the images and one to process them) and would now like to implement these classes into an MFC project. The class works fine in the console app. When I attempted to use them in the MFC app I get LNK2019 errors. Here's some code pieces, the image display class is written in a very similar way:
IMAQ class (for grabing images):
IMAQ.h:
#pragma once
#include <queue>
#include <fstream>
#include "CircularInterface.h"
... // some more includes
class IMAQ
{
public:
explicit IMAQ();
virtual ~IMAQ();
int SetupAcq(pRTCaptureStruc pRTCaptStruc);
... // some more functions
// The image acquisition thread
UINT ImgAcqThread(LPVOID lpdwParam);
private:
BFU32 BdNum,
BdInitOptns,
NumBuffers,
CircInitOptions;
// image acquisition parameters
BFU32 ImageSize,
BitDepth,
Xsize,
Ysize,
NumPixels,
BytesPerPix;
bool GetFrame;
... // some more private members
}; // class IMAQ
IMAQ.cpp:
#include "..\\Include\\IMAQClass.h"
IMAQ::IMAQ()
{
BdNum = 0;
BdInitOptns = CiSysInitialize;
CircInitOptions = BiAqEngJ;
NumBuffers = 4;
FilePath = NULL;
_isClean = true;
}
IMAQ::~IMAQ()
{
// Empty destructor
}
int IMAQ::SetupAcq(pRTCaptureStruc pRTCaptStruc)
{
...// left out code for brevity
}
... // some more functions, all functions declared in header file are defined.
uOCT MFC AppDlg.h:
#pragma once
#include "ImgDspClass.h"
#include "IMAQClass.h"
#include "afxwin.h"
// CuOCTMFCAppDlg dialog
class CuOCTMFCAppDlg : public CDialogEx
{
public:
HBITMAP hBmpWellA6;
BITMAP BmpWellA6;
UINT8 *pBitsWellA6;
BITMAPINFOHEADER bmpInfo;
IMAQ ImgAcq;
ImgDspClass ImgDsp;
char *LUTpath;
char FileName[FILENAME_MAX];
... // more members
};
uOCT MFC AppDlg.cpp:
#include "stdafx.h"
#include "uOCT MFC App.h"
#include "uOCT MFC AppDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
BOOL CuOCTMFCAppDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Change the file path here to change save location
ImgAcq.SetFilePath("C:\\Users\\uOCT clone\\Documents\\temporary\\test.dat");
ImgDsp.SetReferencePath("C:\\Users\\uOCT clone\\Documents\\temporary\\ref.dat");
return TRUE; // return TRUE unless you set the focus to a control
}
In my MFC dialog header file I include the IMAQClass.h header file which is sufficient for the console app to work correctly, yet, as I said above, the MFC app returns unresolved external symbol errors. MFC project seetings additional include directories includes the directory containing IMAQ header file.
Why am I receiving unresolved externals?
Thanks
Error message as requested:
1>uOCT MFC App.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall IMAQ::~IMAQ(void)" (??1IMAQ##UAE#XZ) referenced in function "public: virtual __thiscall CuOCTMFCAppDlg::~CuOCTMFCAppDlg(void)" (??1CuOCTMFCAppDlg##UAE#XZ)
1>uOCT MFC AppDlg.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall IMAQ::~IMAQ(void)" (??1IMAQ##UAE#XZ)
1>uOCT MFC App.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall ImgDspClass::~ImgDspClass(void)" (??1ImgDspClass##UAE#XZ) referenced in function "public: virtual __thiscall CuOCTMFCAppDlg::~CuOCTMFCAppDlg(void)" (??1CuOCTMFCAppDlg##UAE#XZ)
1>uOCT MFC AppDlg.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall ImgDspClass::~ImgDspClass(void)" (??1ImgDspClass##UAE#XZ)
1>uOCT MFC AppDlg.obj : error LNK2019: unresolved external symbol "public: __thiscall ImgDspClass::ImgDspClass(void)" (??0ImgDspClass##QAE#XZ) referenced in function "public: __thiscall CuOCTMFCAppDlg::CuOCTMFCAppDlg(class CWnd *)" (??0CuOCTMFCAppDlg##QAE#PAVCWnd###Z)
1>uOCT MFC AppDlg.obj : error LNK2019: unresolved external symbol "public: __thiscall IMAQ::IMAQ(void)" (??0IMAQ##QAE#XZ) referenced in function "public: __thiscall CuOCTMFCAppDlg::CuOCTMFCAppDlg(class CWnd *)" (??0CuOCTMFCAppDlg##QAE#PAVCWnd###Z)
1>uOCT MFC AppDlg.obj : error LNK2019: unresolved external symbol "public: int __thiscall ImgDspClass::SetReferencePath(char * const)" (?SetReferencePath#ImgDspClass##QAEHQAD#Z) referenced in function "protected: virtual int __thiscall CuOCTMFCAppDlg::OnInitDialog(void)" (?OnInitDialog#CuOCTMFCAppDlg##MAEHXZ)
1>uOCT MFC AppDlg.obj : error LNK2019: unresolved external symbol "public: int __thiscall IMAQ::SetFilePath(char * const)" (?SetFilePath#IMAQ##QAEHQAD#Z) referenced in function "protected: virtual int __thiscall CuOCTMFCAppDlg::OnInitDialog(void)" (?OnInitDialog#CuOCTMFCAppDlg##MAEHXZ)
EDIT: Problem solved, but I guess I don't really understand why.
So the comments posted said that I needed to link to the library file. The two classes I was having a problem with do not generate .dll nor .lib files, just .obj. But on a whim I went back and included the .obj file to the link dependencies.
So now my question is: .obj files need to be linked like libraries if they are not generated along with the executable?
You haven't given us enough detail to help you. You have told us that you are getting a linker error, but you need to tell us the exact error message, i.e., which symbols are undefined?
Here is my guess; you have included an additional header file. This header file is part of a library, but you have not linked in the library itself, only included the header. So you got the first part right, now you need to open up your linker settings page, add the additional library directory (i.e., where the .lib, .obj, .whatever implementation file resides), and then add the name of the library to the "Additional Dependencies" section.
Related
I just created dll project in Visual Studio 2013:New Project->MFC DLL->Next->Check "MFC Extention DLL" and finish.Now, I add new class:
class CMyTest
{
public:
CMyTest();
~CMyTest();
int Test(){ return 1; }
};
Next, I compiled the project and got .lib,.dll files.
In the another project (who using the dll's) I just add the include,lib directory and copy the .dll file to the .exe file location and add the .lib file to Additional Dependency on Linker->Input.
Now, i just create some object from CMyTest class on my OnInitDialog() Method:
CMyTest x;
And when I tried to compiled the project I got Link error:
Error 3 error LNK2019: unresolved external symbol "public: __cdecl CMyTest::CMyTest(void)" (??0CMyTest##QEAA#XZ) referenced in function "protected: virtual int __cdecl CUsingDllProjectDlg::OnInitDialog(void)" (?OnInitDialog#CUsingDllProjectDlg##MEAAHXZ) C:\Users\user\documents\visual studio 2013\Projects\UsingDllProject\UsingDllProject\UsingDllProjectDlg.obj UsingDllProject
Error 4 error LNK2019: unresolved external symbol "public: __cdecl CMyTest::~CMyTest(void)" (??1CMyTest##QEAA#XZ) referenced in function "protected: virtual int __cdecl CUsingDllProjectDlg::OnInitDialog(void)" (?OnInitDialog#CUsingDllProjectDlg##MEAAHXZ) C:\Users\user\documents\visual studio 2013\Projects\UsingDllProject\UsingDllProject\UsingDllProjectDlg.obj UsingDllProject
Where is the problem?
You need to declare the Test method like that (and also the ctr,dctr):
__declspec(dllexport) int Test(){ return 1; }
__declspec(dllexport), instruct the linker to export a symbol to a DLL.you can read about that here: https://msdn.microsoft.com/en-us/library/dabb5z75(VS.80).aspx
I'm getting these error messages
2>main.obj : error LNK2019: unresolved external symbol "public: __thiscall CEngine::CEngine(void)" (??0CEngine##QAE#XZ) referenced in function _WinMain#16
2>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall CEngine::SetWindowSize(int,int,char const *,int)" (?SetWindowSize#CEngine##QAEXHHPBDH#Z) referenced in function _WinMain#16
2>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall CEngine::Begin(void)" (?Begin#CEngine##QAEXXZ) referenced in function _WinMain#16
2>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall CEngine::GetDisplayWidth(void)" (?GetDisplayWidth#CEngine##QAEHXZ) referenced in function _WinMain#16
2>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall CEngine::GetDisplayHeight(void)" (?GetDisplayHeight#CEngine##QAEHXZ) referenced in function _WinMain#16
2>C:\Users\ethan\Desktop\C++ Projects\delveenginetest\Debug\delveenginetest.exe : fatal error LNK1120: 5 unresolved externals
This is my solution:
Solution 'delveenginetest' (2 projects)
DelveEngine
Include
delve.h
Engine.h
SetupSDL.h
stdafx.h
Engine.cpp
Main.cpp
SetupSDL.cpp
This is the code for Engine.h
#pragma once
#include "SetupSDL.h"
class CEngine
{
public:
CEngine(void);
~CEngine(void);
void SetWindowSize(int winW, int winH, const char* GameName, int windowMode);
void Begin(void);
int GetDisplayWidth(void);
int GetDisplayHeight(void);
private:
int deskW;
int deskH;
bool playing;
CSetupSDL* sdl_setup;
};
Code for Engine.cpp
#include "Include/stdafx.h"
#include "Include/Engine.h"
CEngine::CEngine(void)
{
playing = true;
deskW = GetSystemMetrics(SM_CXSCREEN);
deskH = GetSystemMetrics(SM_CYSCREEN);
}
CEngine::~CEngine(void)
{
}
void CEngine::SetWindowSize(int winW, int winH, const char* GameName, int windowMode)
{
// set up SDL for use
sdl_setup = new CSetupSDL(winW, winH, GameName, windowMode);
}
void CEngine::Begin(void)
{
while (playing && sdl_setup->GetMainEvent()->type != SDL_QUIT)
{
sdl_setup->Begin();
sdl_setup->End();
}
playing = false;
}
int CEngine::GetDisplayWidth(void){ return deskW; }
int CEngine::GetDisplayHeight(void){ return deskH; }
The DelveEngine project builds successfully, whereas the delveenginetest project fails.
What's wrong? I've looked everywhere for a reason, can't find one that suits me.
Despite the fact you're not providing all the sufficient information for a correct diagnosis of your problems, I'll try to share what I could imagine that might be the reasons for the linker errors:
I suppose the project delveenginetest you mention is meant to set up unit tests for the classes from the DelveEngine project.
Since you have a Main.cpp in your DelveEngine project, I'd guess it's simply build as an executable (successfully).
Your delveenginetest needs to link to the classes provided from the DelveEngine project, but that's actually not possible, since the .exe from DelveEngine can't be used for linking, you'll need a library to import it to another executable (the unit testing framework).
I'd recommend to separate out your classes/source files from DelveEngine project to make up a static or shared library, that can be linked from an application and the test framework simultaneously from within a single VS solution:
Solution 'DelveEngine' (3 projects)
DelveEngineLib (project [.lib/.dll])
Include
delve.h
Engine.h
SetupSDL.h
Engine.cpp
SetupSDL.cpp
DelveEngine (project [.exe])
Main.cpp
delveenginetest (project [.exe])
Main.cpp (TestFramework main definition)
Since I'm not very versed with it I don't know actually, if VS 2013 supports to setup projects consuming virtual resources (think of links to sources in the actual build environment), but this could be an alternative how to setup application and unit tests without need of an extra library.
I have one solution with 2 projects in it. (VS2013)
One project is a Direct3D with XAML project, the other is a Static class library.
I have set up project dependencies.
I am wondering if the unresolved external symbols could be anything to do with this.
Here are the errors i'm getting... and i'm finding it hard to understand their meaning
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Game::Model::Input::Keyboard::Keyboard(void)" (??0Keyboard#Input#Model#Game##QAE#XZ) referenced in function "public: __cdecl Game::App::App(void)" (??0App#Game##Q$AAA#XZ) C:\Users\James\Documents\Visual Studio 2013\Projects\Games\Jimmy\Game\App.xaml.obj Game
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Game::Model::Entities::Player::Player(void)" (??0Player#Entities#Model#Game##QAE#XZ) referenced in function "public: void __thiscall Game::PlayerRenderer::InstantiateDependantObjects(void)" (?InstantiateDependantObjects#PlayerRenderer#Game##QAEXXZ) C:\Users\James\Documents\Visual Studio 2013\Projects\Games\Jimmy\Game\PlayerRenderer.obj Game
Error 3 error LNK1120: 2 unresolved externals C:\Users\James\Documents\Visual Studio 2013\Projects\Games\Jimmy\Debug\Game\Game.exe 1 1 Game
This is one part of the code it is struggling with:
Model project
Model\Entities\Keyboard.h
#pragma once
namespace Game
{
namespace Model
{
namespace Input
{
class Keyboard
{
public:
Keyboard();
bool Up;
bool Down;
bool Left;
bool Right;
bool Space;
bool Escape;
};
}
}
}
Model\Entities\Keyboard.cpp
#include "pch.h"
#include "Entities\Keyboard.h"
using namespace Game::Model::Input;
Keyboard::Keyboard()
: Up( FALSE ),
Down( FALSE ),
Left( FALSE ),
Right( FALSE ),
Space( FALSE ),
Escape( FALSE )
{}
Game project
Game\App.xaml.h
#pragma once
...
#include "..\Model\Entities\Keyboard.h"
...
using namespace Game::Model::Input;
namespace Game
{
ref class App sealed
{
public:
...
private:
...
Keyboard* keyboard;
...
};
}
Game\App.xaml.cpp
App::App()
{
InitializeComponent();
keyboard = new Keyboard();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
Resuming += ref new EventHandler<Object^>( this, &App::OnResuming );
}
...
Any ideas?
That dialog doesn't do what you hope it does, you are not actually linking your static library project. It used to in old VS versions before VS2010, now it only sets the build order.
Instead, use Project + Properties, Common Properties, References. Click the Add New Reference button and tick your library project.
So I've been trying to fix a weird bug in a game engine SDK where the Windows loading cursor is used instead of the game's own cursor.
The fix for this is here: http://www.crydev.net/wiki/index.php/Use_Custom_Cursor#Step_1:_Fixing_The_Cursor_Bug.
I have followed the fix, but I keep getting these when building the game DLL:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall MODCursor::MODCursor(void)" (??0MODCursor##QAE#XZ) referenced in function "public: __thiscall CGame::CGame(void)" (??0CGame##QAE#XZ) C:\Users\User\Desktop\Crytek\Mods\CryEngine2\Code\Game.obj GameDll
Error 2 error LNK2019: unresolved external symbol "public: __thiscall MODCursor::~MODCursor(void)" (??1MODCursor##QAE#XZ) referenced in function "public: virtual __thiscall CGame::~CGame(void)" (??1CGame##UAE#XZ) C:\Users\User\Desktop\Crytek\Mods\CryEngine2\Code\Game.obj GameDll
Yeah, normally I can fix this issue quite easily by defining the class properly, but it hasn't worked in this case. What can I be doing wrong?
The files are as they are in the guide for the fix, so there isn't really any point in posting the files here since they would be a waste of space on here. If the files are really needed to investigate this issue, I'll upload them if anyone requests them.
Perhaps there's an error within the fix itself? One possible difference from the fix to my build is that the fix is using Visual Studio 2008, I am using Visual Studio 2013.
Maybe try to put it all inside .h file:
#ifndef _MOD_CURSOR
#define _MOD_CURSOR
#include <windows.h>
#include "resource.h"
#undef GetUserName // This is a macro in windows.h, gives issues with GetUserName() of ISystem
class MODCursor : public ISystemEventListener
{
public:
MODCursor() {
gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(this);
m_cursor = LoadCursor((HINSTANCE)g_hInst, MAKEINTRESOURCE(IDC_CURSOR1));
SetCursor(m_cursor);
}
~MODCursor(){
gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(this);
}
private:
virtual void OnSystemEvent( ESystemEvent event,UINT_PTR wparam,UINT_PTR lparam ) {
if(event == ESYSTEM_EVENT_TOGGLE_FULLSCREEN || event == ESYSTEM_EVENT_RESIZE || event == ESYSTEM_EVENT_CHANGE_FOCUS){
if (m_cursor != GetCursor())
SetCursor(m_cursor);
}
}
HCURSOR m_cursor;
};
#endif
I'm trying to wrap a unmanaged C++ DLL with managed C++ and I keep getting linking errors.
even though I include my library.lib in the project and include the correct header file.
This is the managed class:
#pragma once
#include "..\Terminal\Terminal.h"
public ref class ManagedTerminal
{
private:
Terminal * m_unTerminal;
public:
ManagedTerminal(void)
{
m_unTerminal = new Terminal();
}
};
and this is the unmanaged class:
#include "..\Core1.h"
#include "..\Core2.h"
__declspec(dllexport) class Terminal
{
private:
CoreObj m_core;
public:
Terminal();
void Init(char* path, char* filename);
void Start();
void Stop();
void Run();
Array<Report> GetSnapshot();
~Terminal(void);
};
and the errors I get are:
Error 5 error LNK2028: unresolved token (0A0000B3) "public: __thiscall Terminal::Terminal(void)" (??0Terminal##$$FQAE#XZ) referenced in function "public: __clrcall ManagedTerminal::ManagedTerminal(void)" (??0ManagedTerminal##$$FQ$AAM#XZ) ManagedTerminal.obj TerminalWrapper
Error 6 error LNK2019: unresolved external symbol "public: __thiscall Terminal::Terminal(void)" (??0Terminal##$$FQAE#XZ) referenced in function "public: __clrcall ManagedTerminal::ManagedTerminal(void)" (??0ManagedTerminal##$$FQ$AAM#XZ) ManagedTerminal.obj TerminalWrapper
can anybody tell me what's wrong?
thanks :)
You have to match all of the build settings -- specifically the calling conventions (CDECL vs. STDCALL) -- in order to have a successful link.
Since .NET 2.0, you have also had to link to the c-runtime dynamically, so make sure that both the .dll and the managed C++ project do this.
Basically, go into the properties dialog for both projects and make sure that things that affect the call are the same.