Visual C++ Errors C2146, C4430 - visual-c++

Please help to figure out whats wrong with this code.
main.cpp create Object3D which create Box and pass Object3D* pointer to Box.
And there are errors until i remove Object3D declarations from Box.
main.cpp
#include <iostream>
#include "stdafx.h"
#include "Object3D.h"
int _tmain(int argc, _TCHAR* argv[])
{
Object3D obj;
char c;
std::cin >> c;
return 0;
}
Object3D.cpp
#include "Object3D.h"
#include "Box.h"
Object3D::Object3D()
{}
Object3D::~Object3D()
{}
Object3D.h
#ifndef OBJECT3D_H
#define OBJECT3D_H
#include "Box.h"
class Object3D
{
public:
Object3D();
~Object3D();
private:
Box _box_obj; //<<<---ERROR HERE (C2146, C4430)
};
#endif
Box.cpp
#include "Box.h"
#include "Object3D.h"
int Box::Init(Object3D* _obj)
{
obj = _obj;
}
Box::Box()
{}
Box::~Box()
{}
Box.h
#ifndef BOX_H
#define BOX_H
#include "Object3D.h"
class Box
{
public:
Object3D* obj; //<<<---ERROR HERE (C2143, C4430)
int Init(Object3D* _obj); //<<<---ERROR HERE (C2061)
Box();
~Box();
};
#endif

Change Box.h:
#ifndef BOX_H
#define BOX_H
// forward reference possible since the class is not dereferenced here.
class Object3D;
class Box
{
public:
Object3D* obj;
int Init(Object3D* _obj);
Box();
~Box();
};
#endif
The class definition does not use any member of Object3D. Therefore you don't need to know the definition of Object3D but just the fact that it is a class. The forward reference is sufficient and an appropriate tool to resolve a circular dependency.
BTW: The circular reference of object usually includes some "master" objects that own the other objects. It makes sense to change the member name to show the relation rather the type. I would suggest a
Object3D* owner;
when the box owns the obj.

Related

How to export a __interface derived class in visual c++?

I want to export a class type that derives from a __interface(only available for Visual c++),which aiming to create c#-like inteface-oriented experience.
//This wiil be defined in a "Famous.h"
__interface IFoo {
int GetNum();
};
//And this is my implementation.
#include "...Famous.h"
class FooImpl : public IFoo
{
public:
FooImpl(int a);
private:
int a;
};
FooImpl::FooImpl(int a)
{
this->a = a;
}
The problem is ,How could I export the 'FoolImpl' type to use it as follows in another project without refrencing the project directly.I tried dllexport,and tons of errors make me exthausted :(.
#include "..Impl.h"
#include "..Famous.h"
void main(){
IFoo* foo = new FooImpl(2);
...
}
Considering of there's no interface in c++,I replaced the __interface with pure virtual class.
//This wiil be defined in a "Famous.h"
#ifdef FAMOUS_EXPORTS
#define XYZAPI __declspec(dllexport)
#else
#define XYZAPI __declspec(dllimport)
#endif
class XYZAPI IFoo {
virual int GetNum() = 0;//void type also valid.
};
//And this is my implementation(Impl.h).
#ifdef IMPL_EXPORTS
#define XYZAPI __declspec(dllexport)
#else
#define XYZAPI __declspec(dllimport)
#endif
#include "...Famous.h"
class XYZAPI FooImpl : public IFoo
{
public:
FooImpl(int a);
private:
int a;
};
FooImpl::FooImpl(int a)
{
this->a = a;
}
And this is my invocation.
#include "..Impl.h"
#include "..Famous.h"
void main(){
IFoo* foo = new FooImpl(2);
...
}

Passing objects as parameters by another object visual c++

I'm trying to pass an object by reference in c++. I get these errors:
Error 1 error C2061: syntax error : identifier 'Common' graphics.h 6 1 SDLGameDev
Error 2 error C2511: 'void Graphics::CreateWindow(Common &)' : overloaded member function not found in 'Graphics' 4 1 SDLGameDev
I found answers about this area, but not any that covers how to do this:
object1.someFunction(object2);
Here is my code:
//Common.h
#ifndef COMMON_H
#define COMMON_H
#include "SDL.h"
#include "iostream"
class Common{
public:
void Init();
bool GetGameRunState(){ return GameRunState; }
void SetGameRunState(bool x){ GameRunState = x; }
private:
bool GameRunState;
};
#endif
//Commmon.cpp
#include "Common.h"
void Common::Init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
SetGameRunState(true);
}
else
{
SetGameRunState(false);
}
}
//Graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
class Graphics{
public:
void CreateWindow(Common & co);
};
#endif
//Graphics.cpp
#include "Graphics.h"
#include "Common.h"
void Graphics::CreateWindow(Common & co)
{
if (co.GetGameRunState() == true)
{
std::cout << "TEST for CreateWindow()\n";
}
}
//main.cpp
#include "Common.h"
#include "Graphics.h"
Common co;
Graphics go;
int main(int argc, char * args[])
{
co.Init();
go.CreateWindow(co);
while (co.GetGameRunState() == true)
{
std::cout << "Game is running\n";
SDL_Delay(2000);
break;
}
return 0;
}
You haven't included Common.h in the file Graphics.h so it doesn't know about the class.
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "Common.h" // You need this line
class Graphics {
public:
void CreateWindow(Common & co);
};
#endif
I would recommend using singletons and put the initialisation of sdl, creation of the renderer and window etc all together in one class. Your question has already been answered.

Error: Struct already definded in *.Obj

Help, I'm using VC++ and I always get the LNK2005 and LNK1169 Error when running my script, can you guys please tell me why it's happening and how to fix it, Thank you!
Code:
In the Main.cpp
#include "stdafx.h
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "Modifier.h"
using namespace std;
HWND myconsole = GetConsoleWindow();
HDC mydc = GetDC(myconsole);
int main()
{
if (Input.beg("Hello"))
{
cout << "World";
}
cin.ignore();
}
In "Modifier.cpp"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct {
bool beg(string a)
{
string b;
getline(cin, b);
if (b == a)
{
return true;
}
else
{
}
}
} Input;
In "Modifier.h"
#include "Modifier.cpp"
You must change your header declaration: you're inadvertently declaring a different, global "Input" variable in every .cpp that includes "Modifier.h".
SUGGESTION:
// Modifier.h
#ifndef MODIFER_H
#define MODIFIER_H
struct Input {
bool beg(string a)
{
string b;
getline(cin, b);
if (b == a)
{
return true;
}
else
{
}
}
};
#endif
Then, in Modifier.cpp:
#include "Modifier.h"
struct Input globalInput;
You should not include a .cpp in a .h. You should include headers in source files, not vice versa.
And you should definitely consider using a "class" instead of a "struct". Because, frankly, that's what your "Input" is: just a method, no state/no data.

Runtime check failure in CString destructor caused by setting Class ptr to NULL?

so somewhere along the lines of putting this app together I've started to get a runtime check failure stack corruption when the destructor for a cstring class member is called.
I've gotten to the point of trying to debug this by throwing bricks at the issue but still havent root caused it. At the current moment the class that the cstring resides in does nothing but initialize its private string members and set a pointer to another class to NULL.
Interestingly if I do not set the class pointer to NULL and comment out that line the corruption goes away. I think this is somewhat of a red herring, and that something is changing in the way the compiler is putting the code together when it pulls in the .h file that contains theCLog definitions and that would be used since I'm declaring a pointer to that object.
int _tmain(int argc, _TCHAR* argv[])
{
DWORD a = 0xBABA; //just to help catch the corrupter
DWORD b = 0xDFDF;
CStringW startat = L"\\\\anetworkshare\\fre";
CStringW lookfor = L".inf";
DirEnum myEnum(startat,lookfor);
ULONG en = a + b;
en = a - b;
return 0;
}
DirEnum.cpp
DirEnum::DirEnum(CString startingdir,CString fileFilter)
{
m_plogfile = NULL; //If you comment out this line corruption goes away
m_startingdir = L"";
m_extfilter = L"";
if(startingdir.GetLength() > 0)
m_startingdir = startingdir;
if(fileFilter.GetLength() > 0)
m_extfilter = fileFilter;
//following commented out to tshoot
//CLogBase& ref = ref.GetInstance();
//logBase = &ref;
//m_plogfile = new CLog(L"DirEnumerator",L"logfile.txt",logINFO);
}
Now I suspect that something in the log.h file is causing a change to occuur in the ATL or CString libraries but I dont know what. Heres the log.h file
#pragma once
//#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
using namespace std;
#ifndef TYPEDEF_H
#define TYPEDEF_H
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <tchar.h>
#include <time.h>
//simple defines to allow the TCHAR library to be used
typedef std::basic_string<TCHAR> tstring;
typedef std::basic_ostream<TCHAR> tostream;
typedef std::basic_istream<TCHAR> tistream;
typedef std::basic_ostringstream<TCHAR> tostringstream;
typedef std::basic_istringstream<TCHAR> tistringstream;
typedef std::basic_ofstream<TCHAR> tofstream;
#if defined(UNICODE) || defined(_UNICODE)
#define tcout std::wcout
#define tcin std::wcin
#else
#define tcout std::cout
#define tcin std::cin;
#endif
#endif
#if defined DEBUG || defined (_DEBUG)
#define TOCONSOLE
#endif
typedef enum LOGLVL{logERROR =0,logWARN,logINFO,logDEBUG};
//CLogBase os a singleton log class. Intent is that you can establish a reference from anywhere in the project and write to the same file
// without having locking issues or threading issues
class CLogBase
{
public:
static CLogBase& GetInstance(CString logname = L"log.txt",LOGLVL lvl = logWARN);
~CLogBase(void);
tostringstream& GetLog(LOGLVL level);
tostringstream& GetStream(LOGLVL);
void Forceflush();
private:
CLogBase(CString file,LOGLVL lvl);
//our outstream
tostringstream m_os;
tostringstream m_dummy;
tofstream m_filestream;
CString m_filename;
LOGLVL m_reportlvl;
//Private declarations to prevent copy constructors from being invoked; these are do nothig implimentations
CLogBase(CLogBase const&);
void operator=(CLogBase const&);
};
class CLog
{
public:
CLog(CString component);
CLog(CString component,CString logname,LOGLVL lvl);
~CLog();
void Log(LOGLVL,CString message);
void CLog::Flush();
tostringstream& CLog::GetStream(LOGLVL lvl);
private:
CString m_componentname;
CLogBase* m_logBase;
};
I thought I would answer this as I found the issue. this was not a coding problem per se but a visual studio issue.
What happened was that I was storing the direnum.h file and .cpp file in a different directory than the one used for the main project. referencing the header with #include "..\somedir\direnum.h"
at one point in time visual studio reported the file as locked and did I want to overwrite \ cancel etc. I choose overwrite but what seemed to happen was that this caused VS to COPY the files to the current project. All my troubleshooting attempts were being edited in the local somename.h file whtne opened in the editor but the compiler was doing the correct thing and pulling down the .h file from the location above.
removing switching to the now local copy of direnum.h and recompiling fixed this as it was compiling part of the code as ANSI and the other part as WCHAR

Cuda - printing string from object in __global__ function

I am new to CUDA and I am getting a strange error. I want to print a string from a passed object and I get the error "calling host function from global function is not allowed" and I don't know why. But if I want to print an integer (changing get method to return sk1), everything works fine. Here is the code:
class Duomenys {
private:
string simb;
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): simb(""), sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys::Duomenys(string simb1, int sk11, double sk21)
: simb(simb1), sk1(sk11), sk2(sk21) {}
__device__ __host__ string Duomenys::get(){
return simb;
}
};
And here I am calling Duomenys::get from __global__ function:
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.get());
}
EDIT: I am trying to read data from a file and print it in a global function. In this code I am trying read all data and print just one object to see if everything works. This is the error I'm getting:
calling a __host__ function("std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string") from a __global__ function("Vec_add") is not allowed
Code:
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
class Duomenys {
private:
string simb;
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): simb(""), sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys::Duomenys(string simb1, int sk11, double sk21)
: simb(simb1), sk1(sk11), sk2(sk21) {}
__device__ __host__ string Duomenys::print()
{
stringstream ss;
ss << left << setw(10) << simb << setw(10) << sk1 << setw(10) << sk2;
return ss.str();
}
};
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.print());
}
/* Host code */
int main(int argc, char* argv[]) {
setlocale (LC_ALL,"");
vector<Duomenys> vienas;
vector<vector<Duomenys>> visi;
//data reading to vector "vienas" (it works without any errors)
Duomenys *darr;
const size_t sz = size_t(2) * sizeof(Duomenys);
cudaMalloc((void**)&darr, sz);
Vec_add<<<1, 1>>>(visi[0].at(0));
cudaDeviceSynchronize();
cudaMemcpy(darr, &visi[0].at(0), sz, cudaMemcpyHostToDevice);
return 0;
}
Your problem is not with printf function, but with string data type. You cannot use the C++ string type in a kernel. See related question here: Can we use the string data type in C++ within kernels
Why would you pass a string object to printf when the %s format specifier is expecting something else? When I try to do that in ordinary host code, I get warnings about "passing non-POD types through ellipsis (call will abort at runtime)". Note that this problem has nothing to do with CUDA.
But beyond that issue, presumably you're getting string from the C++ standard library. (It's better if you show a complete reproducer code, then I don't have to guess at where you're getting things or what you are including.)
If I get string as follows:
#include <string>
using namespace std;
Then I am using a function defined in the C++ Standard Library. CUDA supports the C++ language (mostly) but does not necessarily support usage of C++ libraries (or C libraries, for that matter) in device code. Libraries are (usually) composed of (at least some) compiled code (such as allocators, in this case), and this code has been compiled for CPUs, not for the GPU. When you try to use such a CPU compiled routine (e.g. an allocator associated with the string class) in device code, the compiler will bark at you. If you include the complete error message in the question, it will be more obvious specifically what (compiled-for-the-host) function is actually the issue.
Use a standard C style string instead (i.e. char[] and you will be able to use it directly in printf.
EDIT: In response to a question in the comments, here is a modified version of the code posted that demonstrates how to use an ordinary C-style string (i.e. char[]) and print from it in device code.
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#define STRSZ 32
using namespace std;
class Duomenys {
private:
char simb[STRSZ];
int sk1;
double sk2;
public:
__device__ __host__ Duomenys(void): sk1(0), sk2(0.0) {}
__device__ __host__~Duomenys() {}
__device__ __host__ Duomenys(char *simb1, int sk11, double sk21)
: sk1(sk11), sk2(sk21) {}
__device__ __host__ char * print()
{
return simb;
}
__device__ __host__ void store_str(const char *str)
{
for (int i=0; i< STRSZ; i++)
simb[i] = str[i];
}
};
__global__ void Vec_add(Duomenys a) {
printf(" %s \n",a.print());
}
/* Host code */
int main(int argc, char* argv[]) {
string host_string("hello\n");
setlocale (LC_ALL,"");
vector<Duomenys> vienas(3);
vienas[0].store_str(host_string.c_str());
vector<vector<Duomenys> > visi(3);
visi[0] = vienas;
//data reading to vector "vienas" (it works without any errors)
Duomenys *darr;
const size_t sz = size_t(2) * sizeof(Duomenys);
cudaMalloc((void**)&darr, sz);
Vec_add<<<1, 1>>>(visi[0].at(0));
cudaDeviceSynchronize();
cudaMemcpy(darr, &(visi[0].at(0)), sz, cudaMemcpyHostToDevice);
return 0;
}
Note that I didn't try to understand your code or fix everything that looked strange to me. However this should demonstrate one possible approach.

Resources