C-callable wrapper around C++ class - c++

I am following a tutorial to create a wrapper around C++ code, so that it can be called from C#.
I get an error compiling the wrapper though.
Header.h
class MyClass{
public:
MyClass(int x, int y);
double GetSum();
private:
int x_;
int y_;
};
Below is the source file (body.cpp)
#include "Header.h"
MyClass::MyClass(int x, int y)
{
x = 8;
y = 8;
}
double MyClass::GetSum()
{
int r = x_ + y_;
return r;
}
The wrapper class/dll is as below
#include "C:\Users\tumelo\Documents\Visual Studio 2012\Projects\Emgu\MyClassCpp\MyClassCpp\Header.h"
#include "C:\Users\tumelo\Documents\Visual Studio 2012\Projects\Emgu\MyClassCpp\MyClassCpp\Body.cpp"
//for the function you want made avaible from the dll
extern "C" __declspec(dllexport) double GetResults(int x, int y)
{
//create an instance of the class
MyClass myClass(int x, int y);
return myClass.GetSum();
}
I get an in the wrapper class right at the return statement. The class method does not seem to be recognised for some reason. The error reads:
error C2228: left of '.GetSum' must have class/struct/union
What puzzles me is that this is copy and paste from the tutorial but mine does not work. What could I be missing?

You meant:
MyClass myClass(x, y);
instead of
MyClass myClass(int x, int y);
What you typed is declaring a function named "myClass" that returns a "MyClass" instance and takes two integers. You meant to instantiate a variable named "myClass" of type "MyClass" by by passing it x and y.

Related

"Missing type specifier - int assumed" cannot be solved by adding "return 0" to the main function

I am trying to figure out how the C++ key word "this" works. I followed the codes below, but it does not pass and show the error of "C4430: Missing type specifier, int assumed"
#include <iostream>
#include <string>
void PrintEntity(const Entity& e);
class Entity
{
public:
int x, y;
Entity(int x, int y)
{
this->x = x;
this->y = y;
PrintEntity(*this);
}
};
void PrintEntity(const Entity& e)
{
std::cout << "Entity" << std::endl;
}
int main()
{
return 0;
}
I reviewed other similar questions, the solutions include adding "return 0" to the Main function or circular dependency. But I don't think these solutions apply for me. Please help me solve it, thanks!
You are trying to declare PrintEntity's interface before the type of its one parameter is even declared, Entity.
You have to declare Entity first (without defining it, as its definition does use PrintEntity), before you use it in PrintEntity's declaration. You can do this by adding the line class Entity; before PrintEntity's declaration.
Once they're both declared, then the definitions are ok.
Important
As suggested in the comments, one more way to have the code compile/work, is to use a so called elaborated type specifier. With reference to the specific example, it is enough to change
void PrintEntity(const Entity& e);
to
void PrintEntity(const class Entity& e);
Keep in mind that you don't have to define everything in the class all at once. Another option is to defer the definition of the constructor to after the definition of PrintEntity:
#include <iostream>
#include <string>
class Entity
{
public:
int x, y;
Entity(int x, int y);
};
void PrintEntity(const Entity& e)
{
std::cout << "Entity" << std::endl;
}
Entity::Entity(int x, int y)
{
this->x = x;
this->y = y;
PrintEntity(*this);
}
In this case you can get rid of the declaration of PrintEntity before the definition of the Entity class because you don't need it yet.

Using a member function pointer within a class with global typedef

I get a compiler error at the line func = &Fred::fa; saying:
[Error] '((Fred*)this)->Fred::func' cannot be used as a member pointer
since it is of type 'fptr {aka double (*)(int, int)}. However, I know that if I define the typedef as a class inside the class
typedef double (Fred::*fptr)(int x, int y);
then it will not error it. But I want to be sure that the typedef is defined outside the class.
What am I doing wrong?
#include <iostream>
typedef double (*fptr)(int x, int y);
class Fred
{
private:
//typedef double (Fred::*fptr)(int x, int y);
fptr func;
public:
Fred()
{
func = &Fred::fa;
}
void run()
{
int foo = 10, bar = 20;
std::cout << (this->*func)(foo,bar) << '\n';
}
double fa(int x, int y)
{
return (double)(x + y);
}
};
int main ()
{
Fred f;
f.run();
return 0;
}
A function and a method are different. You cannot stuff a pointer to the method in a pointer to a function. So
typedef double (*fptr)(int x, int y);
must be
typedef double (Fred::*fptr)(int x, int y);
or you must use a wrapper that hides the differences such as std::function.
What's missing in
#include <iostream>
typedef double (Fred::*fptr)(int x, int y); // Fred unknown.
class Fred
{
...
}
is a forward declaration for Fred. You can't use Fred is the compiler doesn't know Fred exists.
Solution: Forward declare Fred.
#include <iostream>
class Fred;
typedef double (Fred::*fptr)(int x, int y); // Fred known enough to get pointers
class Fred
{
...
}
But what you really want is std::function.

C++ : No matching function for call to std::deque<SnakePart>::emplace_front

Recently I have been working on remaking my remake of the classic snake game, this time employing a deque instead of a linked list for the snake's tail. I construct a tail segment and try to emplace it at the front of the deque and get a strange error.
no matching function for call to 'std::deque<SnakePart>::emplace_front(<brace-enclosed initializer list>)'|
Since I am still quite new to C++ I am clueless as to why this error is occurring. It would be appreciated if someone could help me solve this conundrum.
SnakePart.cpp
http://pastebin.com/verR9bpn
Snake.hhttp://pastebin.com/XUyNAVKK
Minimal Complete & Verifiable Example:
#include <deque>
struct Test {
Test(int x, int y) : x(x), y(y){}
int x;
int y;
};
int main () {
int x = 4, y = 5;
std::deque<Test> tester;
tester.emplace_front({x, y});
return 0;
}
SnakePart.cpp
#include "Snake.h"
#include <deque>
void SnakePart::advance(int x, int y, bool loose_tail = true) {
parts.emplace_front({x, y});
if(loose_tail)
parts.pop_back();
}
Snake.h
#ifndef SNAKE_H_INCLUDED
#define SNAKE_H_INCLUDED
#include <deque>
class SnakeHead {
private:
int posX, posY;
// Snake head functions
void input();
void movement();
};
class SnakePart {
private:
std::deque<SnakePart> parts;
void advance(int x, int y, bool loose_tail);
};
#endif // SNAKE_H_INCLUDED
The emplace_front function takes its arguments and passes to a suitable constructor in the contained object. The Test class doesn't have a constructor which takes a single initializer-list argument. It have a constructor taking two int arguments which means you could use
tester.emplace_front(x, y);
It also have a copy-constructor which means you could do
tester.emplace_front(Test{x, y});
Remove curly braces from emplace_front function params. Semantic of emplace* functions means that arguments passed as like in constructor of container type T. Passing it with {} makes argument type is std::initializer_list.

C++ inherited functions not being found

I new in C++ and I have difficulty to understand how to get my function with inheritance.
I have a Class that is link to another with inheritance, everything work except:
I cannot reach my superclass function.
Here's my class header : Point.h (I don't include the .cpp):
#ifndef Point_H
#define Point_H
#include <iostream>
class Point{
public:
Point();
void set_values (int , int);
void set_values (int , int , int );
void affichervaleurs();
int getX() const { return x; }
int getY() const { return y; }
private:
int x ;
int y ;
int z ;
};
#endif
Now My other class that try to access the function getX from Point.h :
The header : Carre.h
#ifndef Carre_H
#define Carre_H
#include "Point.h"
class Carre : public Point{
public:
Carre();
//Carre(int a , int b);
//Carre(int a, int b):Point(a,b) {};
//Carre(int a, int b, int c):Point(a, b, c) {};
//const Point &pp;
int Aire (){
};
void affichercar(){
};
};
#endif
Carre.cpp
#include <iostream>
using namespace std;
#include "Carre.h"
#include "Point.h"
Carre::Carre():Point(){
};
//Carre::Carre(int a, int b);
//const &pp;
int Aire (){
return (getX() * getY());
};
void affichercar(){
//cout << "Coordonnees X:" << x << endl;
};
It says that my GetX() is undeclared in my Carre.cpp .
Like I said I'm new in C++
Does someone know what I'm missing to make that code work. ?
Your definition is missing the class scope, which makes it a free function instead of a member.
It should be
int Carre::Aire (){
return getX() * getY();
};
In the .cpp file for Carre, the functions Aire and affichercar are global. Presumably you intended:
int Carre::Aire(){
return (getX() * getY());
};
For example.
Declaring function outside class body requires a class specifier:
int Carre::Aire () {
return (getX() * getY());
};
void Carre::affichercar() {
//...
}
Otherwise
int Aire () {
return (getX() * getY());
};
is just another function in global namespace that can exists simutaneously to Carre::Aire().
This is because you are not implementing the Aire function as being part of the Carre class.
Try changing
int Aire (){
to
int Carre::Aire (){
Also, you already have an implementation of the Aire method in the header file. You should either implement the function inline in the header file, or in the .cpp file, but not both. This also applies to your affichercar method.

C++ 'class' type redefinition

I have been attempting to work with classes in c++ for the first time. My circle class and associated header file were working fine, I then moved some files and since then keep getting an error which i have displayed below.
c:\circleobje.cpp(3): error C2011: 'CircleObje' : 'class' type redefinition
c:\circleobje.h(4) : see declaration of 'CircleObje'
CircleObje.h
#ifndef CircleObje_H
#define CircleObje_H
class CircleObje
{
public:
void setCol(float r, float g, float b);
void setCoord(int x, int y);
float getR();
float getG();
float getB();
int getX();
int getY();
};
#endif
CircleObje.cpp
#include "CircleObje.h"
class CircleObje {
float rVal, gVal, bVal;
int xCor, yCor;
public:
void setCol(float r, float g, float b)
{
rVal = r;
gVal = g;
bVal = b;
}
void setCoord(int x, int y)
{
xCor = x;
yCor = y;
}
...
};
I haven't copied all of the .cpp functions as I didn't think they were relevant. These files were working without issue before I moved the file locations. Even after renaming them I still have the same error as above. Any ideas to solve the problem?
The issue is that you are defining the class twice just as the compiler is telling you. In the cpp you should provide the definitions of the functions like so:
MyClass::MyClass() {
//my constructor
}
or
void MyClass::foo() {
//foos implementation
}
so your cpp should look like:
void CirleObje::setCol(float r, float g, float b)
{
rVal = r;
gVal = g;
bVal = b;
}
void CircleObje::setCoord(int x, int y)
{
xCor = x;
yCor = y;
}
...
And all the class variables should be defined in the .h file inside of your class.
You have defined the class twice, in the header and in the cpp, so in the .cpp the compiler sees two definitions. Remove the definition of the class on the .cpp.
Class functions should be implemented in the cpp in this way:
<return_type> <class_name>::<function_name>(<function_parameters>)
{
...
}
Consider this example class:
//foo.hpp
struct foo
{
int a;
void f();
}
The class is implemented in the foo.cpp file:
#include "foo.hpp"
void foo::f()
{
//Do something...
}
you are declaring your class multiple times once in header file and another in .cpp file which is redefining your class.
CircleObje.h
#ifndef CircleObje_H
#define CircleObje_H
class CircleObje
{
public:
void setCol(float r, float g, float b);
void setCoord(int x, int y);
float getR();
float getG();
float getB();
int getX();
int getY();
public:
float rVal, gVal, bVal;
int xCor, yCor;
};
#endif
CircleObje.cpp
#include "CircleObje.h"
void CircleObje::void setCol(float r, float g, float b)
{
rVal = r;
gVal = g;
bVal = b;
}
void CircleObje::setCoord(int x, int y)
{
xCor = x;
yCor = y;
}
Remove class CircleObje {, public and the ending bracket }; and it should work. You already defined your class in the .H, thus no need to redefine it in the CPP.
Also, you should write your member implementation (in CPP file) like this :
float CircleObje::getR() { /* your code */ }
you need to put #pragma once in first line of header file then the errors will be disappears