I'm trying to use emscripten to compile a c++ class and expose bindings. I'm running into an error from the compiler.
#include <emscripten/bind.h>
#include <emscripten/emscripten.h>
using namespace emscripten;
class MyClass {
private:
int _year;
int _month;
int _day;
public:
MyClass() { }
MyClass(int year, int month, int day);
int getMonth();
void setMonth(int);
int getYear();
void setYear(int);
int getDay();
void setDay(int);
bool isLeapYear();
int daysInMonth();
void increment();
void decrement();
};
EMSCRIPTEN_BINDINGS(my_sample_class) {
class_<MyClass>("MyClass")
.constructor<>()
.constructor<int, int, int>()
.function("getMonth", &MyClass::getMonth)
.function("increment", &MyClass::increment)
.function("decrement", &MyClass::decrement)
.property("year",&MyClass::getYear, &MyClass::setYear )
//.property("month", &MyClass::getMonth, &MyClass::setMonth )
//.property("day",&MyClass::getDay, &MyClass::setDay )
;
}
The compiler has no problems with the constructors or the function binding. I run into a problem with the property binding. I only have one uncommented to minimize the errors that I get back (they are just repeats of the same error but for different lines). Here are the errors that I'm getting back.
In file included from MyDate.cpp:1:
In file included from ./MyDate.h:2:
emscripten/bind.h:1393:26: error: implicit instantiation of undefined template 'emscripten::internal::GetterPolicy<int (MyClass::*)()>'
auto gter = &GP::template get<ClassType>;
^
./MyDate.h:37:6: note: in instantiation of function template specialization 'emscripten::class_<MyClass, emscripten::internal::NoBaseClass>::property<int (MyClass::*)(), void (MyClass::*)(int)>' requested here
.property("year",&MyClass::getYear, &MyClass::setYear )
^
emscripten/bind.h:569:16: note: template is declared here
struct GetterPolicy;
^
emscripten/bind.h:1399:33: error: implicit instantiation of undefined template 'emscripten::internal::GetterPolicy<int (MyClass::*)()>'
TypeID<typename GP::ReturnType>::get(),
^
emscripten\1.38.21\system\include\emscripten/bind.h:569:16: note: template is declared here
struct GetterPolicy;
^
2 errors generated.
shared:ERROR: compiler frontend failed to generate LLVM bitcode, halting
I've looked up binding examples and it appears I'm using the right syntax. Does any one have any idea of what I might be doing wrong?
Found the problem!
The getter functions must be marked as const to avoid these errors.
EX:
int getMonth() const;
Related
I'm initiating to C++ and I'm struggling with a compiling problem
I have a source file "binomial.cpp" in which I define the methods of my classes :
#include "binomial.hpp"
using namespace std;
int Bernoulli::operator()(){
return (rand() < p*RAND_MAX) ? a : b;
};
int Binomial::operator()(){
int result(0);
for(int i(0);i<n;++i){
int a;
a = B();
result += a;
};
return result;
};
and a header file "binomial.hpp" where I declare all my classes :
#include <iostream>
#ifndef BINOMIAL
#define BINOMIAL
class RandVar {
virtual int operator()() =0;
};
struct Bernoulli : public RandVar {
Bernoulli(int a = -1,int b = 1, double p = 0.5) : a(a), b(b), p(p) {};
int operator()(){};
private:
int a,b;
double p;
};
class Binomial : public RandVar {
public:
Binomial(Bernoulli B, int n=2)
: B(B), n(n) {}
int operator()(){};
private:
Bernoulli B;
int n;
};
#endif
But when I try to compile that through g++ using the command : g++ -Wall binomial.cpp -o binomial those errors occur :
binomial.hpp: In member function ‘virtual int Bernoulli::operator()()’:
binomial.hpp:14:19: warning: no return statement in function returning non-void [-Wreturn-type]
int operator()(){};
^
binomial.hpp: In member function ‘virtual int Binomial::operator()()’:
binomial.hpp:26:19: warning: no return statement in function returning non-void [-Wreturn-type]
int operator()(){};
^
binomial.cpp: At global scope:
binomial.cpp:4:5: error: redefinition of ‘int Bernoulli::operator()()’
int Bernoulli::operator()(){
^~~~~~~~~
In file included from binomial.cpp:2:0:
binomial.hpp:14:6: note: ‘virtual int Bernoulli::operator()()’ previously defined here
int operator()(){};
^~~~~~~~
binomial.cpp:8:5: error: redefinition of ‘int Binomial::operator()()’
int Binomial::operator()(){
^~~~~~~~
In file included from binomial.cpp:2:0:
binomial.hpp:26:6: note: ‘virtual int Binomial::operator()()’ previously defined here
int operator()(){};
^~~~~~~~
I don't really know how to fix that so if someone can take some time to help a beginner it would be great !
You should replace both
int operator()(){};
with
int operator()();
in the header files. You meant to provide declarations, not definitions. To provide just a declaration (not provide the code right away), just drop the {}.
I do understand why the following would be a problem if no namespaces were used. The call would be ambiguous indeed. I thought "using stD::swap;" would define which method to use.
Why does it work for "int" but not a "class"?
#include <memory>
namespace TEST {
class Dummy{};
void swap(Dummy a){};
void sw(int x){};
}
namespace stD {
void swap(TEST::Dummy a){};
void sw(int x){};
class aClass{
public:
void F()
{
using stD::swap;
TEST::Dummy x;
swap(x);
}
void I()
{
using stD::sw;
int b = 0;
sw(b);
}
};
}
This is the error message:
../src/Test.h: In member function ‘void stD::aClass::F()’:
../src/Test.h:26:9: error: call of overloaded ‘swap(TEST::Dummy&)’ is ambiguous
swap(x);
^
../src/Test.h:26:9: note: candidates are:
../src/Test.h:17:6: note: void stD::swap(TEST::Dummy)
void swap(TEST::Dummy a){};
^
../src/Test.h:10:6: note: void TEST::swap(TEST::Dummy)
void swap(Dummy a){};
^
I thank you very much in advance for an answer.
This line is using argument dependent lookup
TEST::Dummy x;
swap(x);
So it will find both void stD::swap(TEST::Dummy) as well as void TEST::swap(TEST::Dummy) because x carries the TEST:: namespace.
In the latter case int b = 0; the variable b is not in a namespace, so the only valid function to call would be stD::sw due to your using statement.
This question already has an answer here:
g++ error: ‘vec’ does not name a type [duplicate]
(1 answer)
Closed 8 years ago.
Ok so I am trying to map some of my member functions in the .h file this is to be able to use the map when I implement the code. However, after hours I have gotten nowhere so I would like suggestions or if anyone knows how to implement this. For reference these are the errors.
./Assembler.h:51:2: error: C++ requires a type specifier for all declarations
functions["load"] = load;
^~~~~~~~~
./Assembler.h:51:12: error: size of array has non-integer type 'const char [5]'
functions["load"] = load;
^~~~~~
./Assembler.h:51:2: error: duplicate member 'functions'
functions["load"] = load;
^
As for my header file it with the problem coming from the map:
#include <vector>
#include <iostream>
#include <map>
#include <string>
#include <fstream>
using namespace std;
class Assembler {
public:
Assembler(string filename);//Argument will be passed from the os.cpp file
void parse();// Will go through the a file to output the .o file
void load();
void loadi();
void store();
void add();
void addi();
void addc();
void addci();
void sub();
void subi();
void subc();
void subci();
void ander();
void andi();
void xorer();
void xori();
void negate();
void shl();
void shla();
void shr();
void shra();
void compr();
void compri();
void getstat();
void putstat();
void jump();
void jumpl();
void jumpe();
void jumpg();
void call();
void ret();
void read();
void write();
void halt();
void noop();
private:
typedef void (*function)();
map<string, function> functions;
functions["load"] = load;
fstream in, out; //One will be the .s file while the other will be the .o file
string opcode;
int rd, rs, constant, addr, machcode; //Different parts of the instruction
};
Any help or suggestions would be appreciated. Thanks
Only static const integral data members can be initialized within a class. You probably need to move functions["load"] = load; to a function's definition.
And also, you need to change them to:
typedef void (Assembler::*function)();
...
functions["load"] = &Assembler::load;
Within C++ class declaration, you cannot have member initialiser or executable statement, Have this one
functions["load"] = load;
within constructor
Take a look at your class declaration: everything's compiling fine except
functions["load"] = load;
This is an assignment and initializes the functions map with something. That is not allowed in the declaration which is a "contract" (in the case of an interface) or "explanation" of how your class is composed and what methods/members has.
The right spot to put such an initialization is in your constructor's definition (i.e. in the part of the code that actually contains the code of your methods, specifically when the object gets created if you intend to initialize stuff.. i.e. the constructor).
very simple task for me here and I'm not sure why this is giving me problems, I'm simply making two mockup classes try to compile without any logic in their methods whatsoever using headers and declarations already given to me. Honestly this is just a cut and paste job more than anything, and yet I still came across this golden nugget of love -
cbutton.cpp:11:44: error: default argument given for parameter 4 of ‘cio::CButton::CButton(const char*, int, int, bool, const char*)’ [-fpermissive]
cbutton.h:7:5: error: after previous specification in ‘cio::CButton::CButton(const char*, int, int, bool, const char*)’ [-fpermissive]
cbutton.cpp:11:44: error: default argument given for parameter 5 of ‘cio::CButton::CButton(const char*, int, int, bool, const char*)’ [-fpermissive]
cbutton.h:7:5: error: after previous specification in ‘cio::CButton::CButton(const char*, int, int, bool, const char*)’ [-fpermissive]
cbutton.cpp:19:41: error: default argument given for parameter 1 of ‘void cio::CButton::draw(int)’ [-fpermissive]
cbutton.h:11:10: error: after previous specification in ‘virtual void cio::CButton::draw(int)’ [-fpermissive]
cbutton.cpp:53:29: error: ‘virtual’ outside class declaration
Here are the files I'm working with. Thank you everyone, as always!
#include "cfield.h"
namespace cio{
class CButton: public CField{
public:
CButton(const char *Str, int Row, int Col,
bool Bordered = true,
const char* Border=C_BORDER_CHARS);
virtual ~CButton();
void draw(int rn=C_FULL_FRAME);
int edit();
bool editable()const;
void set(const void* str);
};
}
#include "cbutton.h"
namespace cio {
CButton::CButton(const char *Str, int Row, int Col,
bool Bordered = true,
const char* Border=C_BORDER_CHARS){
}
void CButton::draw(int rn=C_FULL_FRAME){
}
int CButton::edit(){
return 0;
}
bool CButton::editable()const {
return false;
}
void CButton::set(const void* str){
}
virtual CButton::~CButton(){
}
}
You specified a default argument in the definition of the function, while they already had a default argument in the class declaration. You can declare default arguments in the class declaration or in the function definition, but not both.
EDIT: Missed the end of your errors: error: ‘virtual’ outside class declaration. It's a rather clear compiler error: virtual keywords belongs to class declarations, not function definitions. Simply remove it from the definition of your destructor.
Corrected source:
namespace cio {
CButton::CButton(const char *Str, int Row, int Col,
bool Bordered, // No default parameter here,
const char* Border){ // here,
}
void CButton::draw(int rn){ // and here
}
CButton::~CButton(){ // No virtual keyword here
}
}
You're not allowed to repeat default arguments when you define a function. They belong only on the declaration. (The actual rule isn't quite that simple, because a definition can also be a definition, but you get the idea...)
You dont include the default parameter in your function definition, the prototype is the only one you need to include the default value into.
#include "cbutton.h"
namespace cio {
CButton::CButton(const char *Str, int Row, int Col,
bool Bordered,
const char* Border){ //remove in def
}
void CButton::draw(int rn){
}
I have the following code (stripped down version from actual project to reproduce
the issue) that results in a compiler error on RHEL5 (g++ version 4.1.2):
----------- driver (test.cpp)--------------
#include <iostream>
#include <classa.hpp>
#include <func.hpp>
namespace globals {
static int kth(const A& a) {
return kth(a.ival());
}
}
using namespace globals;
int main() {
A a;
std::cout << func(a) << std::endl;
return 0;
}
----------class A (classa.hpp)------------
class A {
public:
A():val(0){}
const int ival() const {return val;}
private:
int val;
};
------- namespace globals (func.hpp) ------
namespace globals {
int kth(const int& c) {
return c;
}
template <class T>
int func(const T& key) {
return kth(key);
}
}
--------------------------------------------
Compiling it using g++ 4.1.2 gives me the following error:
func.hpp: In function ‘int globals::func(const T&) [with T = A]’:
test.cpp:15: instantiated from here
func.hpp:8: error: invalid initialization of reference of type ‘const int&’ from
expression of type ‘const A’
func.hpp:2: error: in passing argument 1 of ‘int globals::kth(const int&)’
Same code compiles and runs perfectly fine on RHEL4 (g++ version 3.4.6)! Any explanations/ideas/suggestions on how to resolve this error(?) on RHEL5 will
be much appreciated!
Edit:
Thanks Sergey. That is the obvious solution that I am aware of already. But I forgot to add that the restriction is that func.hpp cannot be edited (for e.g., its 3rd party write-protected). Any workarounds?
Here's what happens. When the function func() is defined, the compiler doesn't know about the function kth(const A&) yet because it is defined later in the code. So when it encounters a reference to kth() inside func(), it assumes that it is a reference to kth(const int&). Now when func() is actually instantiated, it fails to compile it because T is A, not int. I am not sure why it works in another version of the compiler, but I think it is because it actually starts resolving references when a template function is instantiated, not when it is declared. But this looks like a bug in the older version because with such behavior a function definition changes depending on where it is instantiated from, which is very confusing.
The only way to fix your code that it works with any compiler would be to put the definition of kth(const A&) between kth(const int&) and func() or a forward declaration of kth(const A&) somewhere above func().
Update
With the restriction of not editing func.hpp the best workaround I can think of is to create a custom header file with something like this:
#include <classa.hpp>
namespace globals {
static int kth(const A& a); // defined later, but used by func.hpp
}
#include <func.hpp>
I also don't see why kth(const A&) is defined as static, but used by a global header. I'd rather put it into the classa.cpp and its declaration into the classa.hpp. But this may be some design feature or artifact I am not aware of.