I have two classes, and this is the header of one of them:
#ifndef WRAPPER_HPP
#define WRAPPER_HPP
#include <SDL/SDL.h>
using namespace std;
class Wrapper
{
private:
//SDL_Surface *screen;
public:
static SDL_Surface *screen;
static void set_screen(SDL_Surface *_screen);
static void set_pixel(int x, int y, Uint8 color);
static void clear_screen(int r, int g, int b);
static SDL_Surface* load_image(char path[500]);
static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};
#endif
I am calling Wrapper::set_screen(screen) from another file and I get this error:
In file included from /home/david/src/aships/src/Wrapper.cpp:6:0:
/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_screen(SDL_Surface*)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:10:3: error: from this location
I also get a similar error for the definition of every single function on Wrapper.cpp, for example:
void Wrapper::set_pixel(int x, int y, Uint8 color)
{
/* Draws a pixel on the screen at (x, y) with color 'color' */
Uint8 *p;
p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
*p = color;
}
On compile:
/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_pixel(int, int, Uint8)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:17:17: error: from this location
I know it's related to the class being static and thus the variable Wrapper.screen is not accessible or something, but I'm not sure of how to fix it. Any ideas?
You are using a static variable
static SDL_Surface *screen;
in your code.
In C++ when you declare a static variable in the .h (or .hpp) you are creating a variable that is general (static) to the class. Thus, to use it in another file you have to redeclare it (which I'm guessing you didn't) to create a variable in that file referencing the static one. In your case put this:
SDL_Surface* Wrapper::screen;
in the .cpp file.
I'm not sure the theory is well explained, but it works like that.
Your class and member (screen) are not static, which means they don't actually exist.
You can't access a non static member in a static function.
Try to make your data members to be static.
I'm not convinced that the code abstract you show us is an accurate characterization of your problem.
Your header should not include using namespace std; — it doesn't use or declare anything from the std namespace, and specifying using namespace std; is generally regarded as 'not a good idea', doubly so when it appears in a header file.
It also isn't clear that your header needs to include SDL/SDL.h. If the Uint8 type is easily isolated (not necessarily valid), then your header file can simply use a forward declaration of the SDL_Surface class. (Your implementation code will need to include SDL/SDL.h; but you should not burden the users of your wrapper class with unnecessary #include directives when simple forward declarations would suffice.)
This code is self-contained (does not need any headers), but more or less simulates what you could use, and it compiles OK:
#ifndef WRAPPER_HPP
#define WRAPPER_HPP
typedef unsigned char Uint8;
class SDL_Surface;
class Wrapper
{
public:
static SDL_Surface *screen;
static void set_screen(SDL_Surface *_screen);
static void set_pixel(int x, int y, Uint8 color);
static void clear_screen(int r, int g, int b);
static SDL_Surface *load_image(char path[500]);
static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};
#endif
//#include <SDL/SDL.h>
typedef unsigned short Uint16;
class SDL_Surface
{
public:
Uint8 *pixels;
Uint16 pitch;
struct
{
Uint8 BytesPerPixel;
} *format;
};
// End of SDL/SDL.h
void Wrapper::set_pixel(int x, int y, Uint8 color)
{
/* Draws a pixel on the screen at (x, y) with color 'color' */
Uint8 *p;
p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
*p = color;
}
It also compiles without warnings. The (Uint8 *) cast (copied from the original) is unnecessary. With the class definition given, it is superfluous; if you are needing to use a cast because the type of the pixels member of SDL_Surface actually isn't Uint8, are you sure it is a good idea? And can't you use reinterpret_cast<Uint8>(screen->pixels) instead to make it clearer?
Can you reduce your problem to code analogous to this that still shows the actual error?
Related
I am kind of new to C++. I am having trouble setting up my headers. This is
from functions.h
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect *);
And this is the function definition from functions.cpp
void
apply_surface(int x, int y, SDL_Surface * source, SDL_Surface *
destination,SDL_Rect *clip = NULL)
{
...
}
And this is how I use it in main.cpp
#include "functions.h"
int
main (int argc, char * argv[])
{
apply_surface(bla,bla,bla,bla); // 4 arguments, since last one is optional.
}
But, this doesn't compile, because, main.cpp doesn't know last parameter is optional. How can I make this work?
You make the declaration (i.e. in the header file - functions.h) contain the optional parameter, not the definition (functions.cpp).
//functions.h
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect * clip = NULL);
//functions.cpp
void apply_surface(int x, int y, SDL_Surface * source, SDL_Surface *
destination,SDL_Rect *clip /*= NULL*/)
{
...
}
The default parameter value should be in the function declaration (functions.h), rather than in the function definition (function.cpp).
Use:
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect * = NULL);
(note I can't check it here; don't have a compiler nearby).
Strangely enough, it works fine for me if I have a virtual function without a default parameter, and then inheritors in .h files without default parameters, and then in their .cpp files I have the default parameters. Like this:
// in .h
class Base {virtual void func(int param){}};
class Inheritor : public Base {void func(int param);};
// in .cpp
void Inheritor::func(int param = 0){}
Pardon the shoddy formatting
I am following one of Fleeps old tutorials from 2012. I have encountered a speedbump, this error: qualified name is not allowed in member declaration.
I have tried changing the SDK, defining/declaring the class in the main.cpp file. None of this worked.
This is my header file i am encountering the error in.
#pragma once
#include <Windows.h>
#include "d3d9.h"
#include <ctime>
#include <iostream>
#define D3DHOOK_TEXTURES
#define MAX_MENU_ITEMS 6
#define WALLHACK 0
#define CUSTOM_CROSSHAIR 1
#define NO_RECOIL 2
#define UNLIM_AMMO 3
#define AUTO_FIRE 4
#define HIDE_MENU 5
class Hacks {
public:
int m_Stride;
void Hacks::CreateFont(IDirect3DDevice9 *d3dDevice, std::string choiceFont);
void Hacks::InitializeMenuItems();
void Hacks::DrawText(LPCSTR TextToDraw, int x, int y, D3DCOLOR Color);
void Hacks::DrawMenu(IDirect3DDevice9 *d3dDevice);
void Hacks::DrawFilledRectangle(int x, int y, int w, int h, D3DCOLOR Color, IDirect3DDevice9 *d3dDevice);
void Hacks::DrawBorderBox(int x, int y, int w, int h, int thickness, D3DCOLOR Color, IDirect3DDevice9 *d3dDevice);
void Hacks::KeyboardInput();
LPDIRECT3DTEXTURE9 texRed;
LPDIRECT3DTEXTURE9 texGreen;
LPDIRECT3DTEXTURE9 texBlue;
LPDIRECT3DTEXTURE9 texWhite;
D3DVIEWPORT9 ViewPort;
LPD3DXFONT Font;
struct d3dMenuHack {
bool on;
std::string name;
};
d3dMenuHack hack[MAX_MENU_ITEMS];
};
The error is ocouring when i am declaring the "void Hacks::"... functions. Any suggestions?
Maybe nikau6's answer is not so clear at first sight because the code seems identical to the one in the OP.
So, the solution is to remove Hacks:: from all your declarations
While building a legacy Direct Show filter in Visual Studio 2019 I had to set Conformance Mode to No. This allows the code to not conform to the standard /permissive-
The above is poor practice as stated by several people. But with legacy code it's often the not appropriate(or possible) to make it follow best practices.
No qualified names to use in member declarations. Which compiler is used in your book ?
class Hacks {
public:
int m_Stride;
void CreateFont(IDirect3DDevice9 *d3dDevice, std::string choiceFont);
void InitializeMenuItems();
void DrawText(LPCSTR TextToDraw, int x, int y, D3DCOLOR Color);
void DrawMenu(IDirect3DDevice9 *d3dDevice);
void DrawFilledRectangle(int x, int y, int w, int h, D3DCOLOR Color, IDirect3DDevice9 *d3dDevice);
void DrawBorderBox(int x, int y, int w, int h, int thickness, D3DCOLOR Color, IDirect3DDevice9 *d3dDevice);
void KeyboardInput();
LPDIRECT3DTEXTURE9 texRed;
LPDIRECT3DTEXTURE9 texGreen;
LPDIRECT3DTEXTURE9 texBlue;
LPDIRECT3DTEXTURE9 texWhite;
D3DVIEWPORT9 ViewPort;
LPD3DXFONT Font;
struct d3dMenuHack {
bool on;
std::string name;
};
d3dMenuHack hack[MAX_MENU_ITEMS];
};
I have divided my project into this source folders:
src/
src/THREADS
src/UKF_IMU+GPS
src/UKF_WCT
I have declared the structure in this file "src/UKF_IMU+GPS/main_general.h"
main_general.h
//Structure Declarations
struct FD
{
int IMU, GPS;
};
struct S_POS
{
double X=0, Y=0, Z=0;
double Latitude=0, Longitude=0, Altitude=0;
};
struct S_IMU
{
double ACCX=0, ACCY=0, ACCZ=0, GYRX=0, GYRY=0, GYRZ=0;
double ACCX_Bias=0, ACCY_Bias=0, ACCZ_Bias=1, GYRX_Bias=0, GYRY_Bias=0, GYRZ_Bias=0;
double Pitch=0, Roll=0, Yaw=0;
//Variables to Calculate AT
double AT=0;
unsigned int Time=0;
};
struct S_GPS
{
int Date=0, TimeHour=0, NumSatUsed=0;
double Yaw=0, Velocity, Vel_X=0, Vel_Y=0, Vel_Z=0;
double Std_Dev_Lat=0, Std_Dev_Lon=0, Std_Dev_Alt=0;
double HDOP=0;
//Variables to Calculate AT
double AT=0;
unsigned int Time=0;
};
Then, I have declared an structure global variable object in "/src/THREADS/IMUandGPS.cpp"
IMUandGPS.cpp
#include "../UKF_IMU+GPS/main_general.h"
/* Global variables */
struct S_POS POS_Snapshot;
struct S_IMU IMU_Snapshot;
struct S_GPS GPS_Snapshot;
I do some stuff with the structure and it works perfect.
I also use the same global object in the other file "/src/THREADS/Write_IMUAndGPS_OF.cpp"
Write_IMUAndGPS_OF.cpp
#include "../UKF_IMU+GPS/main_general.h"
/* External Global variables */
extern struct S_POS POS_Snapshot;
extern struct S_IMU IMU_Snapshot;
extern struct S_GPS GPS_Snapshot;
I do some stuff with the structure and it works perfect as well.
The problem comes here, I have to use the POS global structure in this file:
"/src/src/UKF_WCT/UKF_Algorithm.cpp"
UKF_Algorithm.cpp
#include "../UKF_IMU+GPS/main_general.h"
/* External Global variables */
extern struct S_POS POS_Snapshot;
PosX = POS_Snapshot.Latitude;
PosY = POS_Snapshot.Longitude;
PosZ = POS_Snapshot.Altitude;
Includes and everything is the same but the compiler gives me an error:
forward declaration of 'struct S_POS' UKF_Algorithm.cpp
invalid use of incomplete type 'struct S_POS' UKF_Algorithm.cpp
invalid use of incomplete type 'struct S_POS' UKF_Algorithm.cpp
invalid use of incomplete type 'struct S_POS' UKF_Algorithm.cpp
PosX,Y and Z are also double so is not type problem...Why could be this problem?
I have already solved it!
The problem was that I had another main_general.h file in "src/UKF_WCT/main_general.h" so the compiler found this file instead of "/UKF_IMU+GPS/main_general.h".
I have changed the name of the file and it works perfect!
I am kind of new to C++. I am having trouble setting up my headers. This is
from functions.h
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect *);
And this is the function definition from functions.cpp
void
apply_surface(int x, int y, SDL_Surface * source, SDL_Surface *
destination,SDL_Rect *clip = NULL)
{
...
}
And this is how I use it in main.cpp
#include "functions.h"
int
main (int argc, char * argv[])
{
apply_surface(bla,bla,bla,bla); // 4 arguments, since last one is optional.
}
But, this doesn't compile, because, main.cpp doesn't know last parameter is optional. How can I make this work?
You make the declaration (i.e. in the header file - functions.h) contain the optional parameter, not the definition (functions.cpp).
//functions.h
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect * clip = NULL);
//functions.cpp
void apply_surface(int x, int y, SDL_Surface * source, SDL_Surface *
destination,SDL_Rect *clip /*= NULL*/)
{
...
}
The default parameter value should be in the function declaration (functions.h), rather than in the function definition (function.cpp).
Use:
extern void apply_surface(int, int, SDL_Surface *, SDL_Surface *,SDL_Rect * = NULL);
(note I can't check it here; don't have a compiler nearby).
Strangely enough, it works fine for me if I have a virtual function without a default parameter, and then inheritors in .h files without default parameters, and then in their .cpp files I have the default parameters. Like this:
// in .h
class Base {virtual void func(int param){}};
class Inheritor : public Base {void func(int param);};
// in .cpp
void Inheritor::func(int param = 0){}
Pardon the shoddy formatting
I am using Microsoft Visual Studio 2010 and the OpenCV 2.3.0 libraries to write up an application for image processing.
I have a piece of code that is erroneous for me and I am not sure how to fix it. I am implementing an application where there will be 2 or 3 windows open at the same time and I want each one of them to be assigned with a different CvMouseCallback function. I want all these CvMouseCallback functions to be in a different class together with another function that returns a pointer to one of these functions according to what the user selects.
My Window.h contains this piece of code.
class Window
{
public:
... // constructors and destructors
void setMouseHandler( CvMouseCallback mouseHandler );
private:
... // other stuff
};
and Window.cpp
#include "stdafx.h"
void Window::setMouseHandler( CvMouseCallback mouseHandler )
{
cvSetMouseCallback( win, mouseHandler, NULL );
}
Now, the MouseHandler.h file
class MouseHandler
{
public:
...
CvMouseCallback selectHandler( int option );
void __cdecl selectROI( int event, int x, int y, int flags, void *param );
private:
Image *in;
Window *win;
void ( CV_CDECL MouseHandler::*callback )( int event, int x, int y, int flags, void *param );
};
and lastly, in MouseHandler.cpp I contain
void __cdecl MouseHandler::selectROI( int event, int x, int y, int flags, void *param )
{
//do something
}
CvMouseCallback MouseHandler::selectHandler( int option )
{
callback = (MouseHandler::selectROI);
return callback;
}
The last bit of information you might need is the definition of CvMouseCallback from the OpenCV library which is
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
Now, the question is: When I return the callback from the last function in MouseHandler.cpp it is underlined with an error saying:
Error: return value type does not match the function type.
I know what it says is that I am trying to impose to that function to return something that does not look like the object it is being asking for. However, it's just a function and if I could do that in the main class it would be ok. My problem is how can selectHandler return a pointer to the selectROI function so that it can be used by another class?
I think that you need to use a static function here:
static void __cdecl selectROI( int event, int x, int y, int flags, void *param );
and
void ( CV_CDECL *callback )( int event, int x, int y, int flags, void *param );
accordingly.
The thing is that this definition:
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
Is not a class member function, while yours is a member of class MouseHandler, which means its a different signature and different parameter list (to accommodate for this). Using static class member function solves it for you.
You'll have to figure out how to pass the object context data to the static function of course.
Your selectROI() method, since it is not static, requires an implicit this parameter as its first argument. If you try making it static, you will have a better chance at getting it working, though really if you are passing it to a C API as you are, you technically need to pass an extern "C" function pointer for everything to be fully proper and portable. That might be a trivial forwarding function like this:
extern "C" void selectROI( int event, int x, int y, int flags, void *param );
Then, if you want your C++ class method to not be static (so it can access class member variables), you just need to pass a pointer to a MouseHandler object as the third argument to cvSetMouseCallback() and you will then receive the same in your callback, which can then look like this:
extern "C" void selectROI( int event, int x, int y, int flags, void *param )
{
static_cast<MouseHandler*>(param)->selectROI( event, x, y, flags);
}