Im creating my first program with C++ and wxwidgets.
When I try to compile the project I get errors.
LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
LNK1120 1 unresolved externals
I have compiled the wxwidgets my self in Visual Studio.
After compiling I created a new C++ empty project in Visual Studio.
I went to configuration and added includes directories:
Configuration properties -> C/C++ -> General -> Additional include directories:
C:\Users\user\source\repos\wxWidgets\include; C:\Users\user\source\repos\wxWidgets\include\msvc
Configuration properties -> Linker -> Additional Library Directories:
C:\Users\user\source\repos\wxWidgets\lib\vc_lib
Then I added 2 classes, cApp and cMain.
cApp.h
#pragma once
#include "wx/wx.h"
#include "cMain.h"
class cApp : public wxApp
{
public:
cApp();
~cApp();
private:
cMain* m_frame1 = nullptr;
public:
virtual bool OnInit();
};
cApp.cpp
#include "cApp.h"
wxIMPLEMENT_APP(cApp);
cApp::cApp() {
}
cApp::~cApp() {
}
bool cApp::OnInit() {
m_frame1 = new cMain();
m_frame1->Show();
return true;
}
cMain.h
#pragma once
#include "wx/wx.h"
class cMain : public wxFrame
{
public:
cMain();
~cMain();
};
cMain.cpp
#include "cMain.h"
cMain::cMain() : wxFrame(nullptr, wxID_ANY, "MyProgram") {
}
cMain::~cMain() {
}
You have 2 problems (after the edit due to the comment below) the following problem:
You're building your application as a console mode application and not a GUI one. While it is possible to use wxWidgets from console applications too, this is probably not what you're trying to do, so ensure that the "Linker|System|SubSystem" option in the properties dialog of your project is set to "Windows".
You don't have wxIMPLEMENT_APP(cApp); macro in your code. Again, it is perfectly possible to avoid it, but this is probably not your goal here, so just add this line. This macro is what defines main or WinMain for your application, depending on the platform.
Your linker wants to find the main entry point (main is the default entry point). The wxIMPLEMENT_APP(cApp) macro on the Windows architecture has the WinMain entry point.
I have three quick solutions.
You can write a macro #define WinMain main before macro wxIMPLEMENT_APP(cApp)
You can tell the linker the name of the entry point(
In your case, the name of the entry point is WinMain).
project properties -> Configuration Properties -> Linker -> Advanced and on the right pane of the dialog is a place for the name of the entry point function.
Your Visual Studio project has a Console SubSystem installed (this SubSystem looks for the default main entry point). You must change the SubSystem value to WINDOWS (this SubSystem looks for the WinMain entry point).
Project properties -> Configuration Properties -> Linker -> System and then set the SubSystem property to Windows (/SUBSYSTEM:WINDOWS)
I have a solution (available on Git at this link) including one project (producing a DLL library) and a native unit test.
Visual Studio Enterprise 2015 with VC++
On Windows 10
The structure of my solution is the following:
./src
+--DelaunayTriangulator.UnitTest
| |--DelaunayTriangulatorTest.cpp
| |--DelaunayTriangulator.UnitTest.vcxproj
+--DelaunayTriangulator
| |--DelaunayTriangulator.cpp
| |--DelaunayTriangulator.h
| |--DelaunayTriangulator.vcxproj
|--Triangulator.sln
The project
My source project works and builds fine. It links some libs (AFAIK, they are basically static libraries) which are just some CGAL stuff I need as dependencies. It also runs fine.
If you have a look at the project, you will find that I link those .lib files as part of Linker options:
<Link>
<AdditionalDependencies>$(CGALDirPath)\build\lib\Debug\CGAL-vc140-mt-gd-4.12.lib;$(CGALDirPath)\auxiliary\gmp\lib\libgmp-10.lib;$(CGALDirPath)\auxiliary\gmp\lib\libmpfr-4.lib;..</AdditionalDependencies>
...
</Link>
The test project
The unit test project has been created by using the native test project walkthrough and template in Visual Studio. The test project is also linking the same .lib files that the source project does. Following is the single test I have:
#include "stdafx.h"
#include "CppUnitTest.h"
#include "../DelaunayTriangulator/DelaunayTriangulator.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace CodeAlive::Triangulation;
namespace TriangulatorUnitTest {
TEST_CLASS(DelaunayTriangulatorTest) {
public:
TEST_METHOD(PerformTriangulation) {
DelaunayTriangulator* triangulator = new DelaunayTriangulator();
int result = triangulator->Perform();
Assert::AreEqual<int>(0, result, L"Wrong result", LINE_INFO());
delete triangulator;
}
}; // class
} // ns
Before I linked those .lib files from CGAL, the project did build but did NOT run at all, showing this error message:
Message: Failed to set up the execution context to run the test
The error
As soon as I added the .lib files, the project did build and the single unit test did run only if I left the Assert line uncommented (I had to comment all the code referencing my source project):
TEST_CLASS(DelaunayTriangulatorTest) {
public:
TEST_METHOD(PerformTriangulation) {
Assert::AreEqual<int>(0, 0, L"Wrong result", LINE_INFO());
}
};
When I uncomment the code referencing my project (using the classes I define in my source project), then the same error message shows up when I try running the test:
TEST_CLASS(DelaunayTriangulatorTest) {
public:
TEST_METHOD(PerformTriangulation) {
DelaunayTriangulator* triangulator = new DelaunayTriangulator();
int result = triangulator->Perform();
Assert::AreEqual<int>(0, result, L"Wrong result", LINE_INFO());
delete triangulator;
}
};
I understand that this is due to some kind of issue with external references. What is wrong here?
So the issue here was kinda peculiar to my configuration but also generic enough to deserve an answer for other devs who might incur in this situation.
The problem was that the .dlls of my source project were not deployed to the test output folder. So you need to set OutDir in your test project properties:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
This will make the test actually copy the dlls not in the solution folder, but in the test project folder, and then the referenced source project dlls will be correctly copied. The test project file did not have an entry for OutDir, it seems that made MSBuild not copy the source artifacts.
This should be easy, I am trying to add a new Console application to the Tesseract solution in VC++ 2008.
General problem: LNK2019 unresolved external symbol. Having difficulty with a new project in the Tesseract solution.
SOLVED:
A coworker in the know found the solution. I didn't list the tesseract*.lib in 'Linker > Input > Additional Dependencies'. Once they are added, it links fine.
MESSY DETAILS:
I followed http://tesseract-ocr.googlecode.com/svn/trunk/vs2008/doc/setup.html#using-the-latest-tesseractocr-sources and everything compiles fine, libraries get generated and all the rest. Proceeding this, I have tried to build my own project in the solution, following https://code.google.com/p/tesseract-ocr/wiki/APIExample. I used the first simple example:
#include <baseapi.h>
#include <leptonica/allheaders.h>
int main()
{
char *outText;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with English, without specifying tessdata path
if (api->Init(NULL, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
// Open input image with leptonica library
Pix *image = pixRead("/usr/src/tesseract-3.02/phototest.tif");
api->SetImage(image);
// Get OCR result
outText = api->GetUTF8Text();
printf("OCR output:\n%s", outText);
// Destroy used object and release memory
api->End();
delete [] outText;
pixDestroy(&image);
return 0;
}
So I discovered I needed to add the additional directories, of course. So I copied all of the project settings from the Tesseract project settings. The problem now is I'm left with a bunch of LNK2019 errors.
'myTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall tesseract::TessBaseAPI::End(void)" (?End#TessBaseAPI#tesseract##QAEXXZ) referenced in function _main'. I have added the same Linker settings as the other projects that compile without issues.
In desperation, I made a replica of one of the other projects, dawg2wordlist. Every setting, all the code beyond unique naming, the directory of my new project is at the same level as the other Tesseract projects. How is it possible that with replicated settings and code that it isn't linking? What is the magic I am missing?
Thanks a lot!
Edit, someone asked for the settings. They are ripped directly from the other projects in the solution.
They are as follows:
Console application
C/C++ > Additional Include Directories: ..\..\api;..\..\ccmain;..\..\ccutil;..\..\ccstruct;..\..\classify;..\..\cube;..\..\cutil;..\..\dict;..\..\image;..\..\neural_networks\runtime;..\..\textord;..\..\viewer;..\..\wordrec;.;..\..\..\include;..\..\..\include\leptonica;..\port
C/C++ > Preprocessor Definitions: WIN32;_DEBUG;_CONSOLE;_WINDOWS;USE_STD_NAMESPACE;$(NOINHERIT)
Linker > General > Additional Library Directories: ..\..\..\lib
Linker > Input > Additional Dependencies: ws2_32.lib user32.lib zlib$(ZLIB_VERSION)-static-mtdll-debug.lib libpng$(LIBPNG_VERSION)-static-mtdll-debug.lib libjpeg$(LIBJPEG_VERSION)-static-mtdll-debug.lib giflib$(GIFLIB_VERSION)-static-mtdll-debug.lib libtiff$(LIBTIFF_VERSION)-static-mtdll-debug.lib liblept$(LIBLEPT_VERSION)-static-mtdll-debug.lib $(NOINHERIT)
Linker > System > SubSystem: Console (/SUBSYSTEM:CONSOLE)
Resources > General > Preprocessor Definitions: MYVERSION="$(LIBTESS_VERSION_R)"
They are all copied from the 'tesseract' project in the solution, along with the resource header, .rc files and main header file.
I am currently trying to learn how to use premake 4 in order to apply it to the OpenGL sdk. I am currently trying to make a Visual Studio 2010 solution that constructs 2 projects, one being a static library, the other contains a single main source file, with the main method.
This project is extremely simple, and is solely for the purpose of learning premake. In the static library project, named Test, I have 2 files, Test.h and Test.cpp. Test.h contains the prototype for the method print(). print() simply prints a line to the console. Using premake, I linked the static library to the Main project, and in main.cpp I have included the Test.h file. My problem is this: in VS2010 I get this error when I attempt to build:
1>main.obj : error LNK2019: unresolved external symbol "void __cdecl print(void)" (? print##YAXXZ) referenced in function _main
1>.\Main.exe : fatal error LNK1120: 1 unresolved externals
Here is my code in the 4 files, the premake4.lua:
solution "HelloWorld"
configurations {"Debug", "Release"}
project "Main"
kind "ConsoleApp"
language "C++"
files{
"main.cpp"
}
configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }
links {"Test"}
project "Test"
kind "StaticLib"
language "C++"
files{
"test.h",
"test.cpp"
}
Test.cpp:
#include <iostream>
void print(){
std::cout << "HELLO" << std::endl;
}
Test.h:
void print();
Main.cpp:
#include <conio.h>
#include "test.h"
int main(){
print();
getch();
return 0;
}
If you are wondering why there is a getch() there, on my computer the console immediately closes once it reaches return 0, so I use getch() to combat that issue, which forces the window to wait until the user has pressed another key. Any advice on this issue would be wonderful, because I simply am not sure what the problem is. If it is something simple please dont castrate me on it, I have very little experience with premake and static libraries, which is why I am trying to learn them.
links {"Test"}
Lua is not Python. Whitespace is irrelevant to Lua, just like whitespace doesn't matter to C++. So your links statement only applies to the "Release" configuration. If you want it to apply to the project as a whole, it needs to go before the configuration statement, just like your kind, files, and other commands.
Premake4 works this way so that you could have certain libraries that are only used in a "Release" build (or Debug or whatever). Indeed, you can put almost any project command under a configuration. So you can have specific files that are used only in a debug build, or whatever.
I have a Visual studio 2005 solution that has two projects. One is a static library and the other is a executable used to test the features in the static library. The static library uses MFC. I got the following errors when I built the solution.
uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2#YAPAXI#Z) already defined in LIBCMTD.lib(new.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (?? 3#YAXPAX#Z) already defined in LIBCMTD.lib(dbgdel.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U#YAPAXI#Z) already defined in libcpmtd.lib(newaop.obj)
uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V#YAXPAX#Z) already defined in LIBCMTD.lib(delete2.obj)
I do not know how to overcome this. Can some one please explain why this error is occuring. Any explanation that gives an overview of .lib files linkage will be highly appreciated.
The CRT libraries use weak external linkage for the new, delete, and DllMain functions. The MFC libraries also contain new, delete, and DllMain functions. These functions require the MFC libraries to be linked before the CRT library is linked.
http://support.microsoft.com/kb/148652
Solution based on VS2005 (Replace Nafxcwd.lib with Uafxcwd.lib for ~VS2013)
go to project>properties>configuration properties>linker>input
add to "Additional dependency" -> Nafxcwd.lib Libcmtd.lib
add to "ignore specific library" -> Nafxcwd.lib;Libcmtd.lib
order of libraries is important( Nafxcwd.lib;Libcmtd.lib).
One thing to try is to make sure you have:
#include "stdafx.h"
as the first line in your .cpp files. I'm sure that's not the answer in all cases, but it made the identical error go away in my case.
I meet this problem in a MFC solution of Visual Studio 2010, while changing Use MFC in a Shared DLL into Use MFC in a Static Library in Project -> Properties -> Configuration Properties -> General.
I solve the problem by the following ways, please locate Project -> Properties -> Configuration Properties -> Linker -> Input at first.
In Debug mode:
Add uafxcwd.lib;Libcmtd.lib in Additional Dependencies.
Add uafxcwd.lib;Libcmtd.lib in Ignore Specific Default Libraries.
In Release mode:
Add uafxcw.lib;Libcmt.lib in Additional Dependencies.
Add uafxcw.lib;Libcmt.lib in Ignore Specific Default Libraries.
Notice:
Don't miss the ; between the two .lib files.
A suffix -d must be added in the files in Debug mode.
be sure that you have #include <afx.h> in "stdafx.h" BEFORE other includes like #include <string>
in config linker input
In additional dependicies put uafxcw.lib;LIBCMT.lib
In Ignore specific put put uafxcw.lib;LIBCMT.lib
Make sure the C++ runtime library that you are linking with is the same on your static library as well as your executable. Check your project properties C/C++->Code generation->runtime library settings.
Typo. One stupid way you got that is instead of include the header, you inlucde the cpp.
e.g.
#include <myclass.cpp> //should be #include <myClass.h>
First, libcmtd.lib is for a debug version and libcmt.lib is for production. Double-check that you're not including both. One place to check is the "Command Line" section of the Configuration Properties/Linker project properties.
If you go to the properties for the project, and open up the Configuration Properties/Linker/Input section, you can "Ingore Specific Library"...try listing libcmtd.lib in that field.
For me, I have a static library compiled with _CRTDBG_MAP_ALLOC, and the application not compiled with _CRTDBG_MAP_ALLOC, I was receiving then LNK2005. I've changed the application to compile with _CRTDBG_MAP_ALLOC, and the LNK2005 disappear.
Got rid of the problem
uafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned __int64)"
In additional dependicies put uafxcw.lib.
In Ignore specific put put uafxcw.lib.
I had created two fresh projects with VS2017, one was working the other not, so I compared what was the difference. The one working was created with File > New Project > Visual C++ > MFC/ATL > MFC Application the one not working was created with File > New Project > Visual C++ > Windows Desktop > Windows Desktop Wizardthen adding MFC. In both cases I was using MFC as static lib. I had figured out two fixes. But before that we have to add imports because the second project had NONE!
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
Now either of the two fixes worked for me:
Project > Properties > Configuration Properties > General > Use of MFC set it to use in a Shared DLL, this should also automatically set C/C++ > Code Generation > Runtime Library to Multi-threaded debug dll /MDd make sure it indeed did that.
Try compile now, for me it worked.
I noticed the working project had some imports in stdafx.h, I copied them into pch.h in the other project, it worked.(Keeping the properties unchanged, so static lib was used). The code copied was this:
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
The other solutions changing Linker settings I tried them but they did not work.
I would appreciate if somebody knows why my solution works, it is weird, why including those headers in pch.h solves a linker issue whereas including those same headers anywhere else triggers that error??
Check the manifest file of both projects, make sure that they are linking the same version of the standard library. Most likely they are not, check the properties->code generation->standard library linking.
I also had a similar problem. The link given by Donnie explains the the reason. The solution was to look at the error messages and then removing those libs involved and adding those libs in the order of MFC libs first and then CRT libs.
The way to do that in vs2008 is given by ali.
I will also add that if you have replaced the new/delete operators (and if so, please do the array and the scalar both), you may need to tag them as __forceinline so that the obj doesn't collide with the lib.
For example, I did these to force aligned allocations and had the same trouble until I did that:
__forceinline void * operator new(size_t size)
{
return _aligned_malloc(size, 16);
}
__forceinline void operator delete(void* ptr)
{
_aligned_free(ptr);
}
__forceinline void * operator new [](size_t size)
{
return _aligned_malloc(size, 16);
}
__forceinline void operator delete [](void* ptr)
{
_aligned_free(ptr);
}
A header file declared and defined a variable. Possible solutions include:
Declare the variable in .h: extern BOOL MyBool; and then assign to it in a .c or .cpp file: BOOL MyBool = FALSE;.
Declare the variable static.
Declare the variable selectany.
https://msdn.microsoft.com/en-us/library/72zdcz6f.aspx
For me the problem was solved by changing
Project -> Properties -> Configuration Properties -> General: Use of
MFC = Use MFC in a Shared DLL
Before it was set to "Use Standard Windows Libraries"
Additionally I had to set the /MD option under
Project -> Properties -> C/C++ -> Code Generation : Runtime Library =
Multi-threaded DLL (/MD)
Another possible cause that I ran across while searching for this answer:
I accidentally left an #include "StdAfx.h" line at the top of a .cpp file that I moved from the application (which uses precompiled headers) into a shared static library (which doesn't use precompiled headers).
Got errors after applying Cipher Saw's solution to vs2015
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "void __stdcall DDX_Control(class CDataExchange *,int,class CWnd &)" (?DDX_Control##YGXPAVCDataExchange##HAAVCWnd###Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "public: int __thiscall CWnd::ExecuteDlgInit(void *)" (?ExecuteDlgInit#CWnd##QAEHPAX#Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(wincore2.obj) : error LNK2005: "public: void __thiscall CMFCDynamicLayout::GetHostWndRect(class CRect &)const " (?GetHostWndRect#CMFCDynamicLayout##QBEXAAVCRect###Z) already defined in uafxcwd.lib(wincore2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "void __cdecl AfxRegisterMFCCtrlClasses(void)" (?AfxRegisterMFCCtrlClasses##YAXXZ) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "protected: void __thiscall CMFCControlContainer::PreUnsubclassControl(class CWnd *)" (?PreUnsubclassControl#CMFCControlContainer##IAEXPAVCWnd###Z) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
1>afxnmcdd.lib(afxctrlcontainer2.obj) : error LNK2005: "public: int __thiscall CMFCControlContainer::SubclassDlgControls(void)" (?SubclassDlgControls#CMFCControlContainer##QAEHXZ) already defined in uafxcwd.lib(afxctrlcontainer2.obj)
Was able to fix them by changing libs list from uafxcw.lib;Libcmt.lib to afxnmcdd.lib;uafxcwd.lib;Libcmtd.lib (debug unicode build)