I'm fairly new to C++, this is also my first post on here. I'm trying to use C++ in an embedded systems project so I can take the OOP approach. I'm using the AVR crosspack toolchain (AVR G++ compiler)
My problem is this:
From what i've read, the heap should not be used for dynamic memory allocation in embedded systems. In any case, there is no implementation for "new" in AVR G++ anyway. I'm using composition, starting with a USART driver (lets call it a service), and a logger (singleton pattern, and also a service).
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, however when I try to compose the objects needed in this way I get the following error:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
My sense is that my syntax for passing in an object as a constructor parameter is wrong, but I'm not sure what it should be as all the examples i can find use the "new" keyword in the constructor definition to create the object on the free store. Can anyone help?
The Code:
In "usart.h":
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
In "logger.h":
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
In "logger.cpp"
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
In "main.cpp":
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
It depends. I'm currently in an embedded project with maximum safety-related requirements, and we use new, but not delete. So we have a heap, but don't allocate "dynamically", because all allocated objects are kept during the runtime.
In any case, there is no implementation for "new" in AVR G++ anyway.
Is this true? I never checked... It might be necessary to provide a heap before being able to use new.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
This is a good idea. ;-) It helps unit-testing.
For your syntactical and design problems: This is how I would write your sources.
"usart.h":
All methods are non-static to have access to member variables.
The const attribute on a return type is doing nothing. Did you mean to declare the method constant? Then const belongs after the parameter list. However, this attribute might be wrong if such a method changes any member variable.
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
Just give and store a reference to the USART to avoid a copy.
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
The member variable _usart is directly initialized in the constructor, before any statement is executed.
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
Provide the USART object on the stack, as the logger.
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
The singleton design pattern is deprecated since it was invented, because it is so hard to test. Simply use just one object or a limiting object factory.
Related
I would like to split a class implementation into three parts, to avoid that users need to deal with the implementation details, e.g., the libaries that I use to implement the functionality:
impl.cpp
#include <api.h>
#include <impl.h>
Class::Class() {
init();
}
Class::init() {
myData = SomeLibrary::Type(42);
}
Class::doSomething() {
myData.doSomething();
}
impl.h
#include <somelibrary.h>
class Class {
public:
Class();
init();
doSomething();
private:
SomeLibary::Type myData;
}
api.h
class Class {
Class();
doSomething();
}
The problem is, that I am not allowed to redefine headers for the class definition. This does not work when I define Class() and doSomething() only in api.h, either.
A possible option is to define api.h and do not use it in the project at all, but install it (and do not install impl.h).
The obvious drawback is, that I need to make sure, that the common methods in api.h and impl.h always have the same signature, otherwise programs using the library will get linker errors, that I cannot predict when compiling the library.
But would this approach work at all, or will I get other problems (e.g. wrong pointers to class members or similar issues), because the obj file does not match the header?
The short answer is "No!"
The reason: any/all 'client' projects that need to use your Class class have to have the full declaration of that class, in order that the compiler can properly determine such things as offsets for member variables.
The use of private members is fine - client programs won't be able to change them - as is your current implementation, where only the briefest outlines of member functions are provided in the header, with all actual definitions in your (private) source file.
A possible way around this is to declare a pointer to a nested class in Class, where this nested class is simply declared in the shared header: class NestedClass and then you can do what you like with that nested class pointer in your implementation. You would generally make the nested class pointer a private member; also, as its definition is not given in the shared header, any attempt by a 'client' project to access that class (other than as a pointer) will be a compiler error.
Here's a possible code breakdown (maybe not error-free, yet, as it's a quick type-up):
// impl.h
struct MyInternal; // An 'opaque' structure - the definition is For Your Eyes Only
class Class {
public:
Class();
init();
doSomething();
private:
MyInternal* hidden; // CLient never needs to access this! Compiler error if attempted.
}
// impl.cpp
#include <api.h>
#include <impl.h>
struct MyInternal {
SomeLibrary::Type myData;
};
Class::Class() {
init();
}
Class::init() {
hidden = new MyInternal; // MUCH BETTER TO USE unique_ptr, or some other STL.
hidden->myData = SomeLibrary::Type(42);
}
Class::doSomething() {
hidden->myData.doSomething();
}
NOTE: As I hinted in a code comment, it would be better code to use std::unique_ptr<MyInternal> hidden. However, this would require you to give explicit definitions in your Class for the destructor, assignment operator and others (move operator? copy constructor?), as these will need access to the full definition of the MyInternal struct.
The private implementation (PIMPL) idiom can help you out here. It will probably result in 2 header and 2 source files instead of 2 and 1. Have a silly example I haven't actually tried to compile:
api.h
#pragma once
#include <memory>
struct foo_impl;
struct foo {
int do_something(int argument);
private:
std::unique_ptr<foo_impl> impl;
}
api.c
#include "api.h"
#include "impl.h"
int foo::do_something(int a) { return impl->do_something(); }
impl.h
#pragma once
#include <iostream>
struct foo_impl {
foo_impl();
~foo_impl();
int do_something(int);
int initialize_b();
private:
int b;
};
impl.c
#include <iostream>
foo_impl::foo_impl() : b(initialize_b()} { }
foo_impl::~foo_impl() = default;
int foo_impl::do_something(int a) { return a+b++; }
int foo_impl::initialize_b() { ... }
foo_impl can have whatever methods it needs, as foo's header (the API) is all the user will see. All the compiler needs to compile foo is the knowledge that there is a pointer as a data member so it can size foo correctly.
I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.
In class Foo I have two methods, assign_handler() and call_handler().
The actual handler code is in the main.cpp which is do_this(). do_this() uses the some global variables in main.cpp,
I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. However I'm having trouble invoking assign_handler() i.e. calling do_this(), from call_handler().
Note: call_handler() itself is call by a sigaction in Foo.
EDIT: I tried producing a MCVE as suggested in the comments. I've used gedit to create the files and compile it using g++ in command line. The code works. However in my Eclipse project I get the errors shown in inline comments of the code.
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
I'll divide my answer in two parts. First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do.
Your question is how to assign a function pointer to a member variable and then call it from a static member function. Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway.
So, something like this:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
A more general way would be to store a function object:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
This way you can assign lots of different stuff as the handler:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
Now what you actually want to do when you are going to handle a signal is a bit more complicated. Remember that signal handlers can only call certain functions (async-signal-safe functions) - otherwise things may get ugly. Therefore there is a common trick that you should perform called the self pipe trick. Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. Then you have another place in your code that calls select on the pipe and then read to read the signal number. You then call the appropriate handler function which is then allowed to do whatever you like.
An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded.
I'm working on a VTK program and have found a class (specifically this one: Image Region) which i need to incorporate into my code. To do so I have made a separate ImageRegion.h and ImageRegion.cpp files so they can be easily included in the project. My Problem here is the
static vtkBorderCallback *New()
function which i do not know how to implement in the .cpp file or, to be quite honest, what purpose it serves at all. What does it do? Is it even necessary to have it?
When compiling I get the error:
/home/Desktop/test/src/ImageRegion.cpp:7:10: error: ‘vtkBorderCallback::vtkBorderCallback’ names the constructor, not the type
My .h file:
//ImageRegion.h
#pragma once
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkAssemblyNode.h>
#include <vtkAssemblyPath.h>
#include <vtkBorderRepresentation.h>
#include <vtkCommand.h>
#include <vtkCoordinate.h>
#include <vtkImageMapper3D.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkPolyData.h>
#include <vtkPropPicker.h>
#include <vtkProperty2D.h>
#include <vtkBorderWidget.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
class vtkBorderCallback : public vtkCommand
{
public:
vtkBorderCallback();
static vtkBorderCallback *New();
virtual void Execute(vtkObject *caller, unsigned long, void*);
void SetRenderer(vtkSmartPointer<vtkRenderer> ren);
void SetImageActor(vtkSmartPointer<vtkImageActor> im);
double coords[6];
private:
vtkSmartPointer<vtkRenderer> Renderer;
vtkSmartPointer<vtkImageActor> ImageActor;
};
And my .cpp file:
//ImageRegion.cpp
#include "ImageRegion.h"
vtkBorderCallback::vtkBorderCallback(){}
static vtkBorderCallback::vtkBorderCallback* New()
{
return new vtkBorderCallback;
}
void vtkBorderCallback::Execute(vtkObject *caller, unsigned long, void*)
{
//Do stuff, from original VTK example code
}
void vtkBorderCallback::SetRenderer(vtkSmartPointer<vtkRenderer> ren) {this->Renderer = ren;}
void vtkBorderCallback::SetImageActor(vtkSmartPointer<vtkImageActor> im) {this->ImageActor = im;}
Any help is much appreciated.
This
static vtkBorderCallback *New();
is a static member function called New, taking no arguments, and returning a pointer to vtkBorderCallback.
In the implementation, you should omit the static. You also need to place the function in the scope of its class:
vtkBorderCallBack* vtkBorderCallback::New()
{// ^^^^^^^^^^^^^^^^^^^
return new vtkBorderCallback; // danger! Caller needs to delete this eventually
}
In VTK nearly all of the classes derive from vtkObjectBase. They should use New() and Delete() to create and delete the objects (the constructor and destructor are protected). These methods include referencing counting to make sure that they get properly shared among other vtkObjects that may use them. There is a VTK macro (vtkStandardNewMacro) that takes care of the implementation of New() and the base class implements Delete(). So for VTK, the best way to implement the static New() method is to use that macro. For your class called vtkBorderCallBack it would look like:
vtkStandardNewMacro(vtkBorderCallBack);
This should go in your .cpp file.
To solve the error, put vtkBorderCallBack:: before New():
vtkBorderCallBack* vtkBorderCallBack::New()
~~~~~~~~~~~~~~~~~~~
{
...
}
He should not omit static since New() is meant as constructor. In this scenario I would rather expect the real constructor to be private. The implementation
static vtkBorderCallback::vtkBorderCallBack* New()
{
return new vtkBorderCallback;
}
is syntactically wrong. It has so be
vtkBorderCallBack* vtkBorderCallback::New()
{
return new vtkBorderCallback;
}
Finally the whole approach is strange. New() is not really required here, and possibly leads to a memory leak. To establish a class-specific memory management overload operators new and delete on a per-class basis. Alternatively, to prevent leaks, do not return a raw pointer; return std::auto_ptr (deprecated) or std::unique_ptr:
std::unique_ptr<vtkBorderCallBack> vtkBorderCallback::New()
{
return std::unique_ptr<vtkBorderCallBack>(new vtkBorderCallback); // uses move c'tor
}
However, std::unique_ptrs are movable but not copyable. But that's the point when leaks have to be prevented. When the pointer returned by New() is spreaded all over the code better use a std::shared_ptr.
If you have only a C++03 compiler I recommend Herb Sutter's Using auto_ptr Effectively.
I'm creating a helper to create multiple inheritance between C++ classes and Lua objects. Because Lua store C/C++ user objects as void *, it's hard to do safe casts when you retrieve objects.
For instance,
if you have
class A { }
class B { }
class C : public A, public B { }
And you pass an object of type C to Lua, you pass the address of the C instance, when you need to cast it to B, the C++ compiler will automatically align the pointer to the position of B in C and thus, it's not safe to cast the void * pointer from C to B directly.
To avoid this issue, I use a kind of converter. In Lua, the objects contains their name as a string, so when you need to cast the object from type to an other type, it uses the converter like this:
converters["B"]["C"](mypointer, myresultpointer);
This is the class that helps creating these converters :
// Common.h
#include <functional>
#include <memory>
#include <unordered_map>
#include <string>
typedef std::function<void (void *, void *)> LuaConverter;
typedef std::unordered_map<
std::string,
std::unordered_map<
std::string,
LuaConverter
>
> LuaConverters;
class LuaeClass {
public:
static LuaConverters converters;
public:
template <class From, class To>
static void createConverter(const std::string &fromName,
const std::string &toName)
{
converters[toName][fromName] = [&] (void *ptr, void *result) -> void {
std::shared_ptr<From> *from = static_cast<std::shared_ptr<From> *>(ptr);
*((std::shared_ptr<To> *)result) = std::static_pointer_cast<To>(*from);
};
}
};
This class is compiled as static library to be used many times in the project.
Object need to be passed as shared_ptr (it also solve the problem of ownership and deletion). It works well, however, it segfaults when using as static libraries.
Then, I have a simple module Battery, compiled as shared object and links to the common library.
For the scope of the example, it does not contains much functions, but it actually use the LuaeClass:
// Battery.cpp
#include <lua.hpp>
#include "Common.h"
class Battery {
public:
int getPercent() {
return 100;
}
};
extern "C" int luaopen_battery(lua_State *L)
{
LuaeClass::createConverter<Battery, Battery>("Battery", "Battery");
return 0;
}
This compiled as a shared object named battery.so, Lua will use dlopen() and dlcose() to load it.
Finally, the main. It links to common also and use it to create objects.
// main.cpp
#include <iostream>
#include <memory>
#include <string>
#include <lua.hpp>
#include "Common.h"
using namespace std;
class LuaDeleter {
public:
void operator()(lua_State *L) {
lua_close(L);
}
};
typedef unique_ptr<lua_State, LuaDeleter> LuaState;
int main(void)
{
LuaState L(luaL_newstate());
luaL_requiref(L.get(), "_G", luaopen_base, 1);
luaL_requiref(L.get(), "package", luaopen_package, 1);
// This will dlopen() and dlclose()
string code = "local battery = require \"battery\"";
LuaeClass::createConverter<int, int>("Int", "Int");
if (luaL_dostring(L.get(), code.c_str()) != LUA_OK) {
cerr << lua_tostring(L.get(), -1) << endl;
}
return 0;
}
To summary:
Common.cpp, Common.h are compiled as simple static library (libcommon.a)
Main.cpp, compiled and links to libcommon.a
Battery.cpp, compiled as a shared object and links to libcommon.a
The main segfaults at exit, the core file says it's in the destructor of std::function<> so I guess it is called multiple times on the same pointer, is it?
Is the static library data shared in all code? How can I avoid this issue?
The begin of the core
#0 0x0000000000404062 in std::__1::function<void (void*, void*)>::~function() ()
#1 0x0000000000404025 in std::__1::function<void (void*, void*)>::~function() ()
The next trace are just unreadable and unusable.
The code and global/static data of static library will be injected into each module which links it. So for your case, there are multiple LuaeClass::converters instances exist in your project. And you need to call luaopen_battery() in each module which links the static library.
I am not sure if your crash has anything to do with static link, but I am quite sure you went to a complicated implementation.
The first issue you want to address is safely converting void* to A*, B*, C*. Which class/interface you want to export to Lua? If it's class C, you can define below methods in class C:
void pushThis(lua_State *L);
static C* getThis(lua_State *L, int idx);
Both methods use C*, so you don't need a convert function. You can use meta table to distinguish your pointers from other userdata. If you need B*, just:
B* b = (B*)C::getThis(L, idx);
And you may not really need a shared_ptr. shared_ptr doesn't help on deleting your C++ object when your Lua object is collected by GC(because the shared_ptr still exist in heap). Instead, you have to implement a __gc callback in the meta table to delete your object.