Drive MFC Application from Win32 Console Application - c++

I have a situation where I need to essentially run some unit tests against a MFC application.
I basically have some gtest code in Win32 Console application that needs to be able to create a instance in code of the MFC application and basically do some assertions etc...
I tried to create a Win32 console application with MFC header included. I then included the header file of my MFC applicaton class. However, whenever I try to create an instance i.e CWindowApplicationApp the_app in my console application, I receive linking error
This is some of the source code from my console application
CWindowApplicationApp the_app;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
}
return nRetCode;
}
error LNK2019: unresolved external symbol "public: __thiscall CWindowApplicationApp::CWindowApplicationApp(void)" (??0CWindowApplicationApp##QAE#XZ) referenced in function "void __cdecl `dynamic initializer for 'the_app''(void)" (??__Ethe_app##YAXXZ)
Any help? I have included the header file paths

The linker is telling you it doesn't know where to find the object code for CWindowApplicationApp's constructor.
You need to link with whatever object files define CWindowApplicationApp (typically WindowApplicationApp.obj), as well as any other object files that are referred to by WindowApplicationApp.obj (very dependent on your app structure).

You are on the wrong road. It is not possible to create an instance of an application inside another application. What will work is to add some test code into the application and rebuild it.

Related

C++ Compiling windows service with visual studio

hope you could help me. I got a C++ source for my service based on Microsoft example, still i get linker error compiling it:
error LNK2019: unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
as the entry point for windows services is int _tmain(int argc, TCHAR* argv[])
In my case it's void __cdecl _tmain(int argc, TCHAR* argv[]) { ... }
There are 1 header and 1 cpp files with a class used by the service and main.cpp contaning entry point and c style service related code. Subsystem is console without any custom entry point set. Still if i add classic int main(...) to the code project compiles yet the service does not start from windows service manager returning error.
Please advise how to compile this using _tmain.
Ok, still no luck with _tmain. Unfortunately i haven't tried to define WINAPI WinMain entry point.
Still if you proceed with wmain program entry point and add code mentioned by Richard Critten for a service startup SCManager performs just fine. For a complete service sample refer to MS doc.wmain will force you to use Unicode yet it shouldn't be such a problem in 2020.
Subsystem should be set as supposed to your needs and no need to set custom entry point.
Thanks to everyone commented.
UPD You have to include tchar.h in order to use _tmain, so all types of entry points will work fine.

Why does LNK2005 Error disappear?

In visual studio 2012 I have a small console c++ project with the following code
Main.cpp:
#include "../TestLib/LibFunction.h"
int _tmain(int argc, _TCHAR* argv[])
{
int number = libFunction(7);
return 0;
}
and in a static library project LibTest I have
LibFunction.h:
#pragma once
int libFunction( int a );
LibFunction.cpp
int libFunction( int a )
{
return a + 1;
}
This compiles and runs fine. (The Library is added as a reference and linked in implicitly)
If I now add this code to main project
int libFunction( int a )
{
return 7 * a;
}
when I try to build the program I get this error
Main.obj : error LNK2005: "int __cdecl libFunction(int)" (?libFunction##YAHH#Z) already defined in TestLib.lib(LibFunction.obj)
which is fair enough. However if I now just try building again ( doing nothing else ) the link completes without error and the program runs fine with the new libFunction being used.
Why does the error go away?
Why is there this inconsistency? Either it is valid to override a function in a library or its not. I should not get an error and then without doing anything get no error.
I am trying to understand the behaviour for a much larger project where again there are duplicate symbols defined in the exe and referenced lib and sometimes I get errors and sometimes not.
Normally it should be OK to override library symbols. There are still caveats; for instance, if library code contains several external functions in the same source file, and you want to override one of them, you may have to override all the others. Otherwise you will get the multiple definitions error. But in this case you will get it consistently.
However such overrides may throw off the incremental linker, especially if it's the first build with the override. A full rebuild should be enough to correct the error until you add more overrides. If this is a problem, just disable incremental linking.

A simple DLL using VS2010 MFC + a test app

I am trying to build a very simple DLL file which supports MFC.
I use VS2010.
All the examples I found on the net shows how to export class function members.
But my client, at the end, should be a C program. Meaning, it doesn't know to use classes and objects.
I just need to export some simple functions for it.
What I did until now is to put the following on my dll cpp file:
extern "C" __declspec(dllexport) CString SayHello (CString strName){
return theApp.SayHello(strName);
}
and on the app class I wrote:
CString CMyDLLApp::SayHello(CString strName){
return (CString)"Hello " + strName;
}
I created a simple dialog based app, which was suppose to use this function like this
CString strResult = SayHello(m_edit);
After I included the DLL h file at the top of the file:
#include "..\MyDll\MyDll.h"
But the compiler says : error C3861: 'SayHello': identifier not found
Can you please guide me how to do it? Don't offer me to not to use MFC on my DLL because I want to use the DB classes of it.
Also, how to tests it? I don't care if the test program itself is MFC based as well.
Try this declaration in your app to get rid of the compiler error:
extern "C" __declspec(dllimport) CString SayHello (CString strName);
But you cannot get theApp directly from within the DLL. Add another DLL function to pass a pointer to theApp to the DLL.

Every time I try to build a simple "hello world" I always get 2 errors

I'm using visual studio 2010.
Every time I try to build a simple "hello world" I always get 2 errors.
Here's the code::
#include <iostream>
using namespace std;
int main ()
{
cout << "Hello World!";
return 0;
}
Error 2 error LNK1120: 1 unresolved externals C:\Users\hershell
kurt\Documents\Visual Studio 2010\Projects\test\Release\test.exe test
Error 1 error LNK2001: unresolved external symbol
_WinMain#16 C:\Users\hershell kurt\Documents\Visual Studio 2010\Projects\test\test\MSVCRT.lib(crtexew.obj) test
How do I fix this?
Strange, I just created an empty project and pasted your code and it works fine for me.
Make sure you created your project as Win32 Console Application, then in the window that appears click next and select "empty project".
You have created Win32 project and there is no "main" function, but WinMain. Google it or use "win32 console application". as Alanir Alonedaw and Tudor stated; Try and create a new project but select console application instead of win32 project.
It should compile correctly after this :)
A win32 project requires a "WinMain" function as opposed to the "main" function required by a console application. A win32 project is typically a GUI based application based on the Windows API
You have created Win32 project and there is no "main" function, but WinMain. Google it or use "win32 console application".

Creating static library and linking to it with premake

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.