Undefined reference to WinMain#16 - Codeblocks - c++

I have read: undefined reference to `WinMain#16' & still don't understand my problem.
I had a program that was working. Added a class but had not implemented it into the program yet just wrote the header and .cpp file. The program previous to just adding this class worked and now it doesn't.
Error states... **file address....libmingw.32.a(main.o):main.c:(.text.startup+0xa7)
Header file
#ifndef DATE_H
#define DATE_H
#include <iostream>
#include <string>
class Date
{
public:
Date();
//Setters
void SetDay(unsigned dy);
void SetMonth(std::string month);
void SetYear(unsigned mnth);
//Getters
unsigned GetDay() const;
std::string GetMonth() const;
unsigned GetYear() const;
private:
unsigned day, year;
std::string month;
};
#endif // DATE_H
.cpp file
#include "Date.h"
Date::Date()
{
day = 0;
year = 0;
month = "Not Set";
}
//Setters
void Date::SetDay(unsigned dy)
{
day = dy;
}
void Date::SetMonth(std::string mnth)
{
month = mnth;
}
void Date::SetYear(unsigned yr)
{
year = yr;
}
//Getters
unsigned Date::GetDay() const
{
return day;
}
unsigned Date::GetYear() const
{
return year;
}
std::string Date::GetMonth() const
{
return month;
}
my main which I call it in, just because I wasn't sure if the error was because it wasn't being called or something like that is:
#include <iostream>
#include <fstream>
#include "unit.h" // Unit class declaration
#include "regist.h" // Registration class declaration
#include "date.h"
using namespace std;
// Main program:
// Open an input file stream, read a Registration object,
// including its list of courses. Redisplay all information,
// and calculate the total credits taken. Write the results
// to a file stream.
int main()
{
ifstream infile( "testin.txt" );
if( !infile ) return -1;
Registration R;
Date D;
infile >> R;
ofstream ofile( "testout.txt" );
ofile << R;
cout << "\nComputation completed. Check output file. \n";
cout << "\n Day is " << D.GetDay;
return 0;
}
Day does not get set in the overloaded >> operator relating to Registration. It is set by the basic constructor.
Again I haven't added this class in to the program as it is going to be I'm just trying to compile after it was write and added in a basic testing manner. Testing through main.
Thanks in advance. =D

The problem is that your new project has been created as a Win32 GUI project, when it should have been created as a Console application. The former requires that a function with the signature int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) exists, while the latter requires one of the usual form taken for C or C++ projects, namely int main() or int main(char *argv[], int argc).
Either create a new project of the console type and copy your code into it, or use the 'sticky-tape' solution, and change int main() to int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) You would also need to navigate to the project's properties and change the Build Target from GUI application to Console application - failing to do so would mean that you would not see any output, since you're using cout, which prints to stdout, which is shown by the console. This window is always available for a console application, but is only available for the Debug version of a GUI application.
I reccomend doing it properly and creating a new project of the appropriate type, namely a Console application. :)

Change the type of your application under your project settings to Console. WinMain16 is related to Windows graphical applications. I believe you do need to set a special preprocessor flag or include a library of some sort to get it to work properly if you keep it as a Windows graphical application, but in this case, the easiest fix would be to just get a console application.
Also, maybe adding the -mwindows flag can help you.

Related

using a callback function from a 3rd party api in your own class that is a dll

I am trying to write a class in a dll that uses a callback function from another dll. currently i can get the callback to work when i am calling it in a main function but i am having problems integrating it in my own dll.
I am using Hinstance in the regular project and the dll im compiling.
This works in a regular project:
void mycallback(float values[], __int64 timestamp, int status) {
//stuff
globalval[0]=values[0];
...
}
void main(){
...
void(*_callback)(float[], __int64, int);
_callback = &mycallback;
API_CALLBACK finalCallBack = (API_CALLBACK)_callback;
....
//I pass this callback in another function that the api uses later
}
However this fails when I try to port it in the initialise function in a class that I am compiling as a dll (I was trying to use bind function but #include was giving me errors (using visual studios 2015)
void MyClass::mycallback(float values[], __int64 timestamp, int status){
//stuff
myClassval[0]=values[0];
...
}
MyClass::Init(){
void(*_callback)(float[], __int64, int);=
_callback = &MyClass::mycallback;<---This line is giving me error
API_CALLBACK finalCallBack = (API_CALLBACK)_callback;
}
The error i get is "assigning to ' void(*)(float *,long long, int)' from incompaible type 'void(MyClass::*)(float *,long long,int)"
Is there a different way I should approach this? I am not sure how to handle this as I have only access to the function callbacks but not the source.
edit: I realise that casting mycallback as static would solve the problem but then I would run into the problem of being unable to store the value somewhere. or is there a good way to do this?
full code for further reference:
void main() {
//declare dll handler
HINSTANCE hinstLib;
FCALL _InitDevices,_ReleaseDevices;
FCALL_GETHMDINFO _getHMDinfo;
FCALL_HMDPRESENT _HMDPresent;
FCALL_STARTTRACKING _StartTracking;
BOOL fFreeResult;
//Load dll
hinstLib = LoadLibrary(TEXT("thirdparty.dll"));
bool* isHMDpresent = new bool;
void(*_hmdcallback)(float[], __int64, int);
_hmdcallback = &hmdcallback;
HMD_TRACK_CALLBACK hmdCallBack = (HMD_TRACK_CALLBACK)_hmdcallback;
//float handle = (float)hmdCallBack;
//if dll present
if (hinstLib != NULL)
{
//initialise devices
_InitDevices = (FCALL)GetProcAddress(hinstLib, "InitDevices");
if (NULL != _InitDevices)
{
std::cout<<(_InitDevices)()<<std::endl;
}
//start tracking
_StartTracking = (FCALL_STARTTRACKING)GetProcAddress(hinstLib, "StartTracking");
if (NULL != _StartTracking)
{
std::cout << (_StartTracking)(hmdCallBack,nullptr,nullptr,nullptr) << std::endl;
}
this is the function from the 3rd party dll
DLL_EXPORT typedef void(__stdcall *HMD_TRACK_CALLBACK)(float values[], __int64 timestamp, int status );
I am trying to convert the above and package it in another dll(a driver) with other functions from multiple dlls. The specific task i am trying to do now is to store an array from the callback of the dll i am using. In this case, one of the things im storing is values[]

Visual Studio doesn't accept class implementation [C++]

I'm trying to move from Dev C++ to Visual Studio while studying C++ (since I'll have to work with the latter) but for some reason, a rather simple class implementation that perfectly works in Dev C++ creates a long list of errors in Visual Studio.
The files are simple:
header file, for the declaration of constructors, variables etc
cpp file, to implement said constructors, functions etc
consoleapplication file (on visual studio), to produce the "main()" function.
stock2.h
#ifndef STOCK2_H_
#define STOCK2_H_
class Stock
{
public:
Stock();
Stock(const char* co, int n = 0, double pr = 0.0);
~Stock();
void show()const;
private:
std::string company;
int shares;
double share_val;
double total_val;
};
#endif
stock2.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include "stock2.h"
Stock::Stock() //default constructor
{
//code
}
Stock::Stock(const char* co, int n, double pr)
{
//code
}
Stock::~Stock()
{
std::cout << "Stock object has been destroyed" << std::endl;
}
//Methods
void Stock::show() const
{
//code
}
ConsoleApplication.cpp
#include "stdafx.h"
#include "stock2.cpp"
int main()
{
using std::cout;
const int STKS = 4;
Stock stocks[STKS] = {
Stock("NanoSmart", 12, 20.1),
Stock("Boffo Objects", 200, 2.0),
Stock(),
Stock("Monolithic Obelisks", 130, 3.25)
};
cout << "Stock Holdings: \n";
for (int st = 0; st<STKS; st++)
stocks[st].show();
return 0;
}
I've tried to find the solution on other questions posted here but I really can't figure out what's wrong here.
I also read that one is not supposed to #include a cpp file since the header should be the link between the main() and the cpp file itself, but if I decide to use #include stock2.H instead of .CPP in consoleapplication, then the compiler can't find the methods implementations anymore.
EDIT: In the rush i forgot to post the errors!
They're all in this form:
Error LNK2005
"public: void __thiscall Stock::update(double)" (?update#Stock##QAEXN#Z) already defined in
ConsoleApplication1.obj ConsoleApplication1 //path\ConsoleApplication1\ConsoleApplication1\stock2.obj
EDIT2: Since many of you are asking me about the "Solution Explorer", I better just add a screenshot to show you how it's made right now
You included stock2.cpp in your ConsoleApplication.cpp. This means all the code inside stock2.cpp is now compiled twice, and the linker shows the error message
Error LNK2005 "public: void __thiscall Stock::<...> already defined
for the now duplicated functions. Simply replace
#include "stock2.cpp"
with
#include "stock2.h"
If you get another error when doing so, please post the error message for this.

Testing DLL in VC++ cannot step into a function

I made a DLL in VC++ using Visual Studio 2008 professional and I'm trying to test(debug) it!
So I made another project but when I try to make a step into a class I made it just steps forward.
I also try click on the class and go to the definition (where it appear Cannot Load Symbol)
I try in tool>>options>>Debuging>>symbols to add the path to the .pdb file
My code as the dll declaration
#pragma once
__declspec(dllexport) long sdk_init();
//__declspec(dllexport) long sdk_release();
__declspec(dllexport) long sdk_connect(long handle);
__declspec(dllexport) long sdk_getObjectList(long handle);
//__declspec(dllexport) long sdk_disconnect(long handle);
__declspec(dllexport) long sdk_playStream(long handle, int idx);
__declspec(dllexport) long sdk_stopStream(long handle, int idx);
and then the implemantetion for instance ~
long sdk_init(){
CDataManager* m_DataManager = new CDataManager();
int i = m_DataManager->InitXns();
if(i == 0){
return 0;
}
return (long) m_DataManager;
}
The class I can't step into is the CDataManager, that is a class created by me.
#include
using namespace std;
#include <list>
class CDataManager :
public IDeviceSink,
public IMediaSink
{
public:
int InitXns(void);
int Connect(int nDeviceId);
int GetObjectList(void);
int RequestLiveStream(int videoSource);
int StopLiveStream(int videoSource);
private:
int m_bInitXns;
int login;
//store in list?
XNS_DEVICE2 m_sDevice;
//safe store?
XNS_OBJECT *m_pObject;
XNS_OBJECT *m_pVideoSource;
public:
CDataManager();
virtual ~CDataManager();
int SetWnd(HWND hWnd);
long OnResponse(XNS_REQUEST* pReq);
long OnEvent(XNS_EVENT* pEvent);
long OnVideo(UINT nMID, XNS_VIDEO_HEADER* pVideo);
long OnAudio(UINT nMID, XNS_AUDIO_HEADER* pAudio);
I managed to fix my problem:
I changed the "Debugger Type" to "Mixed" in configuration properties>>debugging of my test solution
Anyhow, I don't understand the why I need to do that, if someone was an explanation please post.

lnk1136 - invalid or corrupt .lib

I've got a little problem. I got a dll C library, a header file, and all other files needed to call this dll. I've tried calling this dll through third party programs and it is working.
However, when I try calling it directly (dynamic linking at load and using the given header file) I always get the linker error 1136 with mydll.lib.
Using the header file:
#include "windows.h"
#include "mydll.h"
void main() {
bool test;
test = CallDll("MyArg");
}
With code in headerfile as below:
extern "C" bool _stdcall CallDll(char* MyArg);
Using dynamic linking at load time:
#include "windows.h"
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary((LPCSTR)"mydll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll("MyArg");
}
Now what did I do wrong? I doubt the mydll.lib file is broken, because if this were the issue, I couldn't access the dll with a third party program.
Well it was a rather simple solution.
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary(L"mydll.dll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll((char*)"MyArg");
}
Was all it needed...

(C++) Linking with namespaces causes duplicate symbol error

For the past few days, I have been trying to figure out how to link the files for a CLI gaming project I have been working on. There are two halves of the project, the Client and the Server code.
The client needs two libraries I've made. The first is a general purpose game board. This is split between GameEngine.h and GameEngine.cpp. The header file looks something like this
namespace gfdGaming {
// struct sqr_size {
// Index x;
// Index y;
// };
typedef struct { Index x, y; } sqr_size;
const sqr_size sPos = {1, 1};
sqr_size sqr(Index x, Index y);
sqr_size ePos;
class board
{
// Prototypes / declarations for the class
}
}
And the CPP file is just giving everything content
#include "GameEngine.h"
type gfdGaming::board::functions
The client also has game-specific code (in this case, TicTacToe) split into declarations and definitions (TTT.h, Client.cpp). TTT.h is basically
#include "GameEngine.h"
#define TTTtar "localhost"
#define TTTport 2886
using namespace gfdGaming;
void* turnHandler(void*);
namespace nsTicTacToe
{
GFDCON gfd;
const char X = 'X';
const char O = 'O';
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX = true, isMyTurn;
char Player = X, Player2 = O;
int recon(string* datHolder = NULL, bool force = false);
void initMP(bool create = false, string hn = TTTtar);
void init();
bool isTie();
int turnPlayer(Index loc, char lSym = Player);
bool checkWin(char sym = Player);
int mainloop();
int mainloopMP();
}; // NS
I made the decision to put this in a namespace to group it instead of a class because there are some parts that would not work well in OOP, and it's much easier to implement later on.
I have had trouble linking the client in the past, but this setup seems to work.
My server is also split into two files, Server.h and Server.cpp.
Server.h contains exactly:
#include "../TicTacToe/TTT.h" // Server needs a full copy of TicTacToe code
class TTTserv;
struct TTTachievement_requirement {
Index id;
Index loc;
bool inUse;
};
struct TTTachievement_t {
Index id;
bool achieved;
bool AND, inSameGame;
bool inUse;
bool (*lHandler)(TTTserv*);
char mustBeSym;
int mustBePlayer;
string name, description;
TTTachievement_requirement steps[safearray(8*8)];
};
class achievement_core_t : public GfdOogleTech {
public: // May be shifted to private
TTTachievement_t list[safearray(8*8)];
public:
achievement_core_t();
int insert(string name, string d, bool samegame, bool lAnd, int lSteps[8*8], int mbP=0, char mbS=0);
};
struct TTTplayer_t {
Index id;
bool inUse;
string ip, sessionID;
char sym;
int desc;
TTTachievement_t Ding[8*8];
};
struct TTTgame_t {
TTTplayer_t Player[safearray(2)];
TTTplayer_t Spectator;
achievement_core_t achievement_core;
Index cTurn, players;
port_t roomLoc;
bool inGame, Xused, Oused, newEvent;
};
class TTTserv : public gSserver {
TTTgame_t Game;
TTTplayer_t *cPlayer;
port_t conPort;
public:
achievement_core_t *achiev;
thread threads[8];
int parseit(string tDat, string tsIP);
Index conCount;
int parseit(string tDat, int tlUser, TTTplayer_t** retval);
private:
int parseProto(string dat, string sIP);
int parseProto(string dat, int lUser);
int cycleTurn();
void setup(port_t lPort = 0, bool complete = false);
public:
int newEvent;
TTTserv(port_t tlPort = TTTport, bool tcomplete = true);
TTTplayer_t* userDC(Index id, Index force = false);
int sendToPlayers(string dat, bool asMSG = false);
int mainLoop(volatile bool *play);
};
// Other
void* userHandler(void*);
void* handleUser(void*);
And in the CPP file I include Server.h and provide main() and the contents of all functions previously declared.
Now to the problem at hand
I am having issues when linking my server. More specifically, I get a duplicate symbol error for every variable in nsTicTacToe (and possibly in gfdGaming as well). Since I need the TicTacToe functions, I link Client.cpp ( without main() ) when building the server
ld: duplicate symbol nsTicTacToe::PlayerIsX in Client.o and Server.o
collect2: ld returned 1 exit status
Command /Developer/usr/bin/g++-4.2 failed with exit code 1
It stops once a problem is encountered, but if PlayerIsX is removed / changed temporarily than another variable causes an error
Essentially, I am looking for any advice on how to better organize my code to hopefully fix these errors.
Disclaimers:
-I apologize in advance if I provided too much or too little information, as it is my first time posting
-I have tried using static and extern to fix these problems, but apparently those are not what I need
Thank you to anyone who takes the time to read all of this and respond =)
You get error about duplicate definitions because that's what you have: each time a .cpp file includes TTT.h, a global bool PlayerIsX is defined (in the nsTicTacToe namespace, but still global). In this case, it's Server.cpp and Client.cpp that are including it.
One way to solve this could be to change the definitions into declarations by using extern, then doing the actual definition in a corresponding .cpp file (TTT.cpp, for instance).
In TTT.h:
namespace nsTicTacToe {
...
extern bool PlayerIsX;
...
}
In TTT.cpp:
#include "TTT.h"
bool nsTicTacToe::PlayerIsX;
and so on for the other definitions.
By the way, remember to have proper guard #ifdefs:
#ifndef __TTT_H
#define __TTT_H
... header contents
#endif // __TTT_H
Actually, extern IS what you need. You're probably just not realizing or remembering that you'll also have to define such variables in a cpp file.
header:
extern int somevar;
source:
int somevar = ?;
By putting all of your globals in the header you're making copies of them everywhere you include them, which is exactly what your compiler is bitching about.
You are essentially using globals, which is strongly not recommended in C++, but is sometimes necessary in C.
You could get it working with extern, but the "better" answer would be to wrap your globals in a state object of some sort.
struct State
{
GFDCON gfd;
const char X;
const char O;
string MPhostname, mySID;
board TTTboard;
bool PlayerIsX, isMyTurn;
char Player, Player2;
};
Create your state object in Main and pass it to each function that needs to know the state of the game system.
This will lead to much better code organization in the long run.
you could put the namespace nsTicTacToe part into it's own .cpp file, compile it separately and link it in.
You might also need a header file which just declares externs for the variables, and include that in you client and server .cpp files.