I am using OOLUA 2.0.0 and am receiving the error undefined reference to OOLUA::Proxy_class<TestClass>::class_name.
The code is:
class TestClass
{
int test_member;
public:
void setTestMember(int x) { test_member = x; }
int getTestMember() { return test_member; }
};
OOLUA_PROXY(TestClass)
OOLUA_MEM_FUNC(void, setTestMember, int)
OOLUA_MEM_FUNC(int, getTestMember)
OOLUA_PROXY_END
int main()
{
OOLUA::Script script;
script.register_class<TestClass>();
OOLUA::run_chunk(script, "local n = TestClass.new() \n n:setTestMember(42) \n print(\"test_member is: \" .. n:getTestMember()");
return 0;
}
The documentation here does not appear to say anything about this error. I'm not sure what class_name even is. Any help is appreciated.
By the way, I'm using GCC 4.9.2 to compile it.
So this is late but hopefully it will help if anyone else runs across a similar issue. Basically your example is missing an important but subtle part that will help explain why you got the link errors you got.
TestClass.hpp
class TestClass
{
int test_member;
public:
void setTestMember(int x) { test_member = x; }
int getTestMember() const { return test_member; }
static void aStaticMember() { }
};
OOLUA_PROXY(TestClass)
OOLUA_MEM_FUNC(void, setTestMember, int)
OOLUA_MEM_FUNC_CONST(int, getTestMember)
OOLUA_SFUNC(aStaticMember)
OOLUA_PROXY_END
TestClass.cpp
OOLUA_EXPORT_FUNCTIONS(TestClass
,setTestMember
)
OOLUA_EXPORT_FUNCTIONS_CONST(TestClass
,getTestMember
)
You must always put a OOLUA_EXPORT_FUNCTIONS block in the associated .cpp file so that the declarations from the OOLUA_PROXY block are defined. Even if you only have const member functions, you must still place an empty block e.g. OOLUA_EXPORT_FUNCTIONS(TestClass) in the .cpp file. In the event that your class only has static functions, you would be required to use a slightly different setup.
In summary:
OOLUA_PROXY declares a proxy class
OOLUA_EXPORT_FUNCTIONS blocks define the members of that class
Also, if your class has only static member functions exposed, you will need to include a OOLUA_EXPORT_NO_FUNCTIONS(TestClass) in the .cpp file. For every static member you must then use special syntax for registering the static functions with the Script.
using namespace OOLUA; //NOLINT(build/namespaces)
Script vm;
vm.register_class_static<TestClass>("aStaticMember",
&OOLUA::Proxy_class<TestClass>::aStaticMember);
The documentation is not very helpful in this matter, but if you reveiw the associated test source files, they in combination with the documentation are enough to get past most issues.
It would be better posting questions about the library to the mailing list oolua.org/mailinglist
Have a look at the documentation for the library, specifically exporting class functions[1]. Personally I would use the minimalist DSL for your functions instead of the expressive, this would then make your proxied functions like the following (however the get should really be a constant function):
OOLUA_MFUNC(setTestMember)
OOLUA_MFUNC(getTestMember)
[1] https://docs.oolua.org/_o_o_lua_proxying.html
Related
I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!
I'm aware of using function prototypes, and I was under the impression that forward class declarations could serve a similar purpose when main() and a class are in the same file. For example, I would have expected this would compile:
// main.cpp
#include <iostream>
// class prototypes
class MyClass;
int main(void)
{
MyClass myClass;
// do stuff with myClass here
return(0);
}
class MyClass
{
public:
int someInt;
double someDouble;
// more stuff here . . .
};
But on the MyClass myClass; line I'm getting the error 'myClass' uses undefined class 'MyClass'. What am I doing wrong?
P.S. I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
P.P.S. I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
Forward declarations can only be used via pointers or references.
Calling a constructor function doesn't fall into this category.
I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
That's why usually header files are used, instead of placing all the declarations and definitions in the main.cpp file.
I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
You should still stick to that idiom though, everything else would probably end up in a mess.
This doesn't use forward declarations but it partially addresses the spirit of a single main.cpp with your "main" at the top. I find this technique sometimes useful when you want to share something via an online C++ ide where a single file is much easier to deal with, and you want to focus on the action in main rather than implementation detail in helper structs/classes etc.
#include <iostream>
template<typename MyClass,typename MyOtherClass>
int main_()
{
MyClass a;
a.do_foo();
MyOtherClass b;
b.do_bar();
return 0;
}
struct MyClass
{
void do_foo() { std::cout << "MyClass: do_foo called\n"; }
};
struct MyOtherClass
{
void do_bar() { std::cout << "MyOtherClass: do_bar called\n"; }
};
int main()
{
return main_<MyClass,MyOtherClass>();
}
For many times now, I have had problems with the declaration and definition order in C++:
struct A {
void Test() { B(); }
};
void B() {
A a;
}
Of course this can be solved by predeclaring B(). Usually this is good enough to solve any of these problems. But when working with module based header-only libraries or similarily complex include systems, this declaration/definition concept can be really painful. I have included a simple example below.
Nowadays most modern language compilers do a two-pass over the source files to build the declarations in the first pass and process the definitions in the second one. Introducing this scheme into C++ shouldn't break any old code either. Therefore,
Why hasn't this, or a similar approach, been introduced into c++ already?
Are there any relevant clauses in the current standard inhibiting this approach?
Example
This is an example of a module based header library, which has blocking includes because of missing predeclarations. To solve this, the user of the library would have to predeclare the "missing" classes, which is not feasible.
Of course this problem might be solved by using a common include header that orders all declarations before definitions, but with a two-pass this code would also work, no modification required.
oom.h
#pragma once
#include "string.h"
struct OOM {
String message;
};
string.h
#pragma once
#include "array.h"
struct String {
Array data;
};
array.h
#pragma once
struct Array {
void Alloc();
};
#include "oom.h"
void Array::Alloc() { throw OOM(); }
str_usage.cpp
#include "string.h"
int main() {
String str;
}
void f(int);
void g() { f(3.14); }
void f(double);
g currently calls f(int), because it's the only f visible. What does it call in your world?
If it calls f(double), you just broke copious existing code.
If you came up with some rules to make it still call f(int), then that means if I write
void g2() { f2(3.14); }
void f2(double);
and then introduce a worse match for the argument - say, void f2(int); before g2, g2 will suddenly start calling the wrong thing. That's a maintainability nightmare.
A much simpler solution is to separate class definitions from function definitions:
struct A {
void Test();
};
struct B {
A a;
};
inline void A::Test() {
B();
}
There are ambiguities in the C++ grammar that can only be resolved if you know what an identifier refers to.
For example:
a * b;
can be either a multiplication if a is a variable, or a pointer declaration if a is a type. Each of these leads to a different parse tree, so the parser must know what a is.
This means that parsing and name resolution cannot be performed in separate passes, but must be done in one pass, leading to the requirement to pre-declare names.
Most classes appear to be separated between declaration and definition in the following form using namespace qualifier to define the class:
// test.h
class test
{
public:
void func1(void);
private:
void func2(void);
};
// test.cpp
void test::func1(void)
{
//whatever
}
void test::func2(void)
{
//whatever
}
Why don't we typically see people use the keyword class in the .cpp file? Like in the following form:
// test.cpp
class test {
void func1(void)
{
//whatever
}
void func2(void)
{
//whatever
}
};
Is it just convention to use the namespace qualifiers? Or because it make more sense when you starting implementing a class via multiple source files?
Let's view this question from another angle...
It is possible to use the same syntax for both, but it's "the other one"; the following is perfectly valid:
namespace ns
{
int foo();
}
int ns::foo() { return 0; }
Looked at like this, it's the opposite question that's interesting, "why is it common to include the word 'namespace' in .cpp files?"
There's one substantial difference between namespaces and classes that makes namespace {} necessary in so many places: namespaces are open to extension, but classes are defined entirely by their (one and only) definition.
Like with classes, you can't add anything to a namespace using the syntax above; you can't add a function bar above with only int ns::bar() { return 9; }, the only way to add names to a namespace is "from within".
And, as many have discovered, it's convenient to wrap an entire file in a namespace and not use the qualified names, even if you're not adding any names to it.
Hence the popularity of "namespace": it's a convenience enabled by the extensibility of namespaces.
Another issue is that the meaning of your "test.cpp" would depend on whether the class definition has already been seen by the compiler – without it, that's a valid and complete definition of a class with two private functions.
This kind of "action from a distance" depending on possibly very distant code is painful to work with.
It's also worth noting that namespaces were added some twenty years after "C with classes" was created, when C++ was a well established language, and changing the meaning of a construct that literally hasn't changed in decades is pretty much unthinkable.
Partularly if all it does is save a few keystrokes.
Greetings,
I'm having a weird seg fault problem. My application dumps a core file at runtime. After digging into it I found it died in this block:
#include <lib1/c.h>
...
x::c obj;
obj.func1();
I defined class c in a library lib1:
namespace x
{
struct c
{
c();
~c();
void fun1();
vector<char *> _data;
};
}
x::c::c()
{
}
x::c::~c()
{
for ( int i = 0; i < _data.size(); ++i )
delete _data[i];
}
I could not figure it out for some time till I ran nm on the lib1.so file: there are more function definitions than I defined:
x::c::c()
x::c::c()
x::c::~c()
x::c::~c()
x::c::func1()
x::c::func2()
After searching in code base I found someone else defined a class with same name in same namespace, but in another library lib2 as follows:
namespace x
{
struct c
{
c();
~c();
void func2();
vector<string> strs_;
};
}
x::c::c()
{
}
x::c::~c()
{
}
My application links to lib2, which has dependency on lib1. This interesting behavior brings several questions:
Why would it even work? I would expect a "multiple definitions" error while linking against lib2 (which depends upon lib1) but never had such. The application seems to be doing what's defined in func1 except it dumps a core at runtime.
After attaching debugger, I found my application calls the ctor of class c in lib2, then calls func1 (defined in lib1). When going out of scope it calls dtor of class c in lib2, where the seg fault occurs. Can anybody teach me how this could even occur?
How can I prevent such problems from happening again? Is there any C++ syntax I can use?
Forgot to mention I'm using g++ 4.1 on RHEL4, thank you very much!
1.
Violations of the "one definition rule" don't have to be diagnosed by your compiler. In fact, they are often only going to be known at link time when you link multiple object files together.
At link time, the information about the original class definitions may not exist any more (they are not needed after the compiler step) so having multiple definitions of a class is typically not easy to flag to the user.
2.
Once you have two distinct definitions pretty much anything can happen, you are in the territory of undefined behaviour. Whatever happens, it's a possible outcome.
3.
The most sensible thing to do is to communicate with the other members of your team. Agree who's going to use which namespaces and you won't get these problems. Otherwise, you point a documentation tool or static analysis tool over your entire project. Many such tools will be able to diagnose multiple inconsistent definitions of classes.
Just a guess but I don't see any using namespace x; so perhaps it used one namespace instead of the other?
With the advent of templates it became necessary to allow multiple definitions of a body of code with the same name; there was no way for the compiler to know if the same template code had already been generated in another compilation unit i.e. source file. When the linker finds these duplicates, it assumes they are identical. The burden is on you to make sure that they are - this is called the One Definition Rule.
On the linker level this is library interpositioning. The effective symbol bound unfortunately depends on the order of object files on linker command line (this is, sigh, historical).
From what you describe it looks that lib1 comes first in linker argument list and lib2 comes second and interposes on symbols from lib1. This explains the calls to constructors and destructors from the lib2 but calls to func1 from lib1 (since there's no func1-derived symbol in lib2, so there's no "hiding", the call is bound to lib1.)
The solution to this particular problem is to reverse the order of libraries on the linker invocation command.
There's lots of answers about the one definition rule. However, to me, this looks a lot more like a missing copy constructor.
To elaborate:
If the copy constructor is called on your object, then you will get a memory leak. This is because delete will be called on the same set of pointers twice.
namespace x
{
struct c
{
c() {
}
~c() {
for ( int i = 0; i < _data.size(); ++i )
delete _data[i];
}
c(const c & rhs) {
for (int i=0; i< rhs.size(); ++i) {
int len = strlen(rhs[i]);
char *mem = malloc(len + 1);
strncpy(mem, rhs[i], len + 1);
_data.push_back(mem);
}
void fun1();
vector<char *> _data;
};
}