BGI in updated wxDevCpp does not work - c++

I need to use BGI graphics in my program and it worked just fine in the wxDevCpp 7.3. But now I installed an updated version of this IDE 7.4, did everything by instruction http://www.cs.colorado.edu/~main/bgi/dev-c++/, just like before, but now when I try to compile any simple program like
#include <graphics.h>
int main( )
{
initwindow(400, 300, "First Sample");
circle(100, 50, 40);
while (!kbhit( ))
{
delay(200);
}
return 0;
}
I get multiple errors saying that
initwindow(), circle(), kbhit(), delay()
were not declared in the scope. I have no idea what to do.
The change in updated wxDevCpp is the different folder structure, but I copypasted the graphics.h and libbgi.a in several folders. I did not forget to add the linker commands just as the instruction said, but it does not work.
Also, I found another graphics.h which came along with installation of new wxDevCpp and though it might bring a conflict, so I just removed it. No change :(

I think I solved it! It was actually trouble with the graphics.h
When I copypasted all the graphics.h into my .cpp, the compiler gave an error that int right was declared twice in the following code:
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
redefinition of int right, so as it is just a prototype, I change it to:
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
Now it works!!!

Related

Codeblocks Console Application Settings: Undefined reference to WinMain

Edit with respect to solution suggestion:
The solution for the author of the question was that he put the main function into a namespace. Then he added parameters to the main function, then he used extern "C" in order to get his main to be recognized as entry point.
Answers, which looked detailed suggested that the code author did not define a main/win main function (which was debated). I also don't use Visual C++, but a mingw version which works on my AMD computer (its a win 64 variant on a windows 10 home edition).
I have a problem, which seems frequently to find its way to StackOverflow and I could not locate any answer which helped me resolve my problem.
I used codeblocks and made a project as a console application.
This is the code I tried to compile and I keep on getting the "undefined WinMain" error.
I used the win64 MinGW compiler, which came with codeblocks
Compiler Flags were: (-std=C++11, -std=C++14, and -std=C++17. I used all of previous one at a time, before), -Wall, and -pedantic
This is the code and naturally, I was not able to resolve my problem. The attached images are "Build log" and "Build Messages" from the respective codeblock tabs of the "Logs & other window".
Please help.
#include <iostream>
using namespace std;
class Rectangle {
protected:
int width, height;
public:
Rectangle(int width = 0, int height = 0): width(width), height(height) {};
int get_width() const {return width;}
int get_height() const {return height;}
virtual void set_width(int width) {this->width = width;}
virtual void set_height(int height) {this->height = height;}
int area() const {return width * height;}
};
class Square : public Rectangle {
public:
Square(int size = 0) : Rectangle(size, size) {
set_width(size);
this->width = this->height = size;
}
void process(Rectangle &r){
r.set_height(10);
cout << "expected area was 30, got " << r.area() << std::endl;
}
int main() {
Rectangle r(3,4);
process(r);
std::cout << "Template" << std::endl;
return 0;
}
};
Possibly this is part of the solution:
I know that extra compiler flags can be created.
This is a warning, which showed, after I wrapped my main function with extern "C" as suggested by one of the answers in your solution suggestion
||warning: command line option '-std=c17' is valid for C/ObjC but not for C++|.
In my case I chose the option, where it said -std=c++17, still this warning came up.

Undefined reference to WinMain#16 - Codeblocks

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.

Redefinition of int right error using winbgim library

I have a problem with making a program that uses winbgim.h header file. It is a simple program that makes just one simple circle. I am currently learning about winbgim and graphics.h libraries. I downloaded it, I downloaded the library and included it in Codeblocks following this and it works properly.
But when I try to use it, another code pops out and on the 302nd line it stands "error: redefinition of "int right". I am making this in a console file in Codeblocks IDE.
Can anyone help? Here is my code:
#include <iostream>
#include <winbgim.h>
#include <cstdlib>
using namespace std;
int main()
{
int gdriver = 9;
int gmode = 2;
initgraph(&gdriver,&gmode, "");
setbkcolor(WHITE);
setcolor(BLACK);
cleardevice();
circle(320,240,180);
getch();
closegraph();
return 0;
}
I don't know whether it suits this forum or not but I just wanted to tell (the world) something. I recently decided to try out WinBGIm library, so I downloaded the package and after setting up all the compiler and linker settings, ran my simple "Hello World" Code. But I got the following message from my compiler (MinGW, CodeBlocks IDE).
d:\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1........\include\graphics.h|302|error:
redefinition of 'int right'|
d:\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1........\include\graphics.h|302|error:
'int right' previously declared here|
||=== Build finished: 2 errors,
0 warnings ===|
After having googled the problem I found out nothing (If you don't count a suggestion to use CodeBlocks-EP as a Solution).
As I was taking a look at the header files, I found the problem (yeah!!!)
The problem was with the function printimage.
The original declaration was
//The original declaration. Note that there are two "right" variables
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
So what I did is that, I simply changed one of the "right" (the later former one) variable to "top". That's it.
//The corrected code
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int top=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
I did the same thing as #Puneet suggested, just change the name of one of the variables named "right".
The thing that I want to add is that you can't change the name within codeblocks (at least I couldn't do it, the changes were ignored). So I suggest you save your code file/s, close the IDE, and open the "graphics.h" file with a text editor, change the name, save, and you are all set.
You can find your MinGW directory by opening a new codeblocks project, right click in the <iostream> and select something like open file, which will open the header in a new codeblocks "tab", right click the tab and click open containing folder. Thats it.

GLFW setting callback functions

What data type to use when setting a callback functions in GLFW?
I try setting a function to type void but gives me a compile error. Changing it to void __stdcall gives me an RT error, but how do I use the typedef's of GLFW such as GLFW*fun? I think this is the right one to do. I really need an example source code.
btw, I define GLFW as GLFW_DLL
UPDATE
My code's look like this:
(I did it in three ways)
1
prototype. because these* are below main
this one gives me a compile error(invalid conversion)
void MouseClick(int, int);
void Keyboard(int, int);
//...
2
//appending `__stdcall` get compiled but gives me `RT error`
void __stdcall MouseClick(int, int);
void __stdcall Keyboard(int, int);
3
on my other project, I use GLFW_BUILD_DLL and compiles in MSVS with casting.
glfwSetKeyCallback((GLFWkeyfun)Keyboard);
but now, I can't do it in MinGW with the GLFW_DLL
void MouseClick(int x, int y) {
}
in main...
int main() {
//glfw intialization...
glfwSetKeyCallback(Keyboard);
//other setters
}
but, how do I do it this way?
GLFWmouseposfun MousePos {
}
//...
According to the documentation for GLFW v2.x the prototype for what you pass to glfwSetKeyCallback (etc.) is
void GLFWCALL functionname( int key, int action );
Here is a complete C program which will print out the key events:
#include <stdio.h>
#include <GL/glfw.h>
void GLFWCALL keyfun(int key, int action) {
printf("%d %d\n", key, action);
}
int main() {
glfwInit();
glfwOpenWindow(640, 480, 0, 0, 0, 0, 0, 0, GLFW_WINDOW);
glfwSetKeyCallback(keyfun);
while(1) {
glfwSwapBuffers();
}
}
If this code doesn't work you are likely linking to GLFW incorrectly.
Ahm, sorry my fault. I just didn't noticed that I have this Vec2f To_OGL_Coords(int x, int y) inside void MousePos(int x, int y) which I haven't included in my post.
As I said, it is Vec2f which I left out the 3rd(z) coordinate to NULL that causes the runtime error. Method number 2 should work here, same as Jacob Parker's answer. I just really don't know much the effects of those pointers if not used correctly.
(PS. I am working on 2D that's why I neglected the z-coordinate. My bad)

Adding dll's to the project and making functions work

I have to do one project and I was given dll and a header file with implemented functions needed for the project. I was told just to add the header file to the project but this way i get unresolve externals error if i try to use functions referenced in header. So what needs to be done to make everything work? Visual Studio 2010.
Here are the files i have: http://www.ipix.lt/images/33871682.png
And this is header file:
#ifndef __BIM482_RADAR__
#define __BIM482_RADAR__
int BIM482OpenRadar();
int BIM482AddPlane(double x, double y);
int BIM482SetPlaneColor(int planeidx, int coloridx);
int BIM482SetPlanePos(int planeidx, double x, double y);
void BIM482UpdateRadar();
#endif // __BIM482_RADAR__
I need to initiate gui with OpenRadar and pass information with those functions. How to start this thing?
You don't have a .lib-file to link against.
Maybe this can help you
http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/
or this:
http://support.microsoft.com/default.aspx?scid=kb;en-us;131313
or this:
http://www.asawicki.info/news_1420_generating_lib_file_for_dll_library.html
when you have generated the lib-file ,you must use __declspec(dllimport) on yuor functions in the header file.
An alternative to all of the above is to use LoadLibrary(...) in your source and write wrapper function for those function in the dll and call those dll funcions via GetProcAddress(...).
struct
{
HMODULE hDll;
int (*BIM482OpenRadar) ();
int (*BIM482AddPlane) (double x, double y);
int (*BIM482SetPlaneColor) (int planeidx, int coloridx);
int (*BIM482SetPlanePos) (int planeidx, double x, double y);
void (*BIM482UpdateRadar) ();
} dll_funcs = {0};
bool ExitRadar( LPCTSTR szDllPath )
{
if (dll_funcs.hDll)
FreeLibrary( dll_funcs.hDll );
return true;
}
bool InitRadar( LPCTSTR szDllPath )
{
if (dll_funcs.hDll)
return true;
dll_funcs.hDll = LoadLibrary( szDllPath );
if (!dll_funcs.hDll)
return false;
dll_funcs.BIM482OpenRadar = (int(*)())GetProcAddress( dll_funcs.hDll ,("BIM482OpenRadar") );
dll_funcs.BIM482AddPlane = (int(*)(double,double))GetProcAddress( dll_funcs.hDll ,("BIM482AddPlane") );
dll_funcs.BIM482SetPlaneColor = (int(*)(int,int))GetProcAddress( dll_funcs.hDll ,("BIM482SetPlaneColor") );
dll_funcs.BIM482SetPlanePos = (int(*)(int,double,double))GetProcAddress( dll_funcs.hDll ,("BIM482SetPlanePos") );
dll_funcs.BIM482UpdateRadar = (void(*)())GetProcAddress( dll_funcs.hDll ,("BIM482UpdateRadar") );
return true;
}
int BIM482OpenRadar ()
{ return (*dll_funcs.BIM482OpenRadar)(); };
int BIM482AddPlane (double x, double y)
{ return (*dll_funcs.BIM482AddPlane)( x ,y ); }
int BIM482SetPlaneColor (int planeidx, int coloridx )
{ return (*dll_funcs.BIM482SetPlaneColor)( planeidx ,coloridx ); }
int BIM482SetPlanePos (int planeidx, double x, double y)
{ return (*dll_funcs.BIM482SetPlanePos)( planeidx ,x ,y ); }
void BIM482UpdateRadar ()
{ return (*dll_funcs.BIM482UpdateRadar)(); }
There is a windows call that loads a DLL into your image. You can either add it to the compile setup in Visual Studio, or load it dynamically.
The easiest thing is probably to do it at compile time; google "Visual Studio llinking options".
You'll need to export the function from dll, while import the function from your exe. Like:
#if defined(XYZLIBRARY_EXPORT) // inside DLL
#define XYZAPI __declspec(dllexport)
#else // outside DLL
#define XYZAPI __declspec(dllimport)
#endif // XYZLIBRARY_EXPORT
int XYZAPI BIM482OpenRadar();
int XYZAPI BIM482AddPlane(double x, double y);
int XYZAPI BIM482SetPlaneColor(int planeidx, int coloridx);
int XYZAPI BIM482SetPlanePos(int planeidx, double x, double y);
void XYZAPI BIM482UpdateRadar();
In DLL, i suggest to add a macro, and add XYZLIBRARY_EXPORT in pre-processor
It will export all of your function.
In EXE, import the function, without adding pre-processor, as it will import the function by default.
In addition to including header files, you need to link your program with the corresponding libraries. From your screenshot, you seem to have .a files, which are indeed libraries, but unfortunately they are meant for use with the GCC toolchain and will not work with Visual Studio. You either need to get .lib files if you must use Visual Studio, or otherwise switch to a GCC port such as MinGW.
You may use windows API LoadLibrary to load the dll during runtime, followed by GetProcAddress to retrieve function address. With the function address is retrieved, you need to declare the method signature so that compiler know how to call given function.
Below is a sample code for how to "link" to function in Dll:
HINSTANCE m_hExtDll = LoadLibrary( "SDL.dll" )
if (m_hExtDll)
{
FARPROC m_pfnOpenRadar = GetProcAddress(m_hExtDll, "BIM482OpenRadar")
if (m_pfnOpenRadar)
{
typedef int (*OPENRADARFUNC)();
OPENRADARFUNC fnOpenRadar = (OPENRADARFUNC)m_pfnOpenRadar;
int iRetCode = fnOpenRadar();
}
}
Do note that functions exported are subject to name mangling and you can verify the function name using third-party utility like Dependency Walker.