I want to do something like this:
struct CLI_Command{
CLI_Command(char* s, void (*h)(void)){
command_string = s;
handler = h;
}
char* command_string;
void (*handler)(void);
};
class CLI {
public:
CLI();
private:
CLI_Command cli_table[NO_CLI_COMMANDS] = {
CLI_Command("Command1", handler1),
CLI_Command("Command2", handler2)
};
void handler1(){};
void handler2(){};
};
I know that I need something similar to CLI::*handler, but I can't get the syntax right. I keep running into errors like this:
"error: no matching function for call to 'CLI_Command::CLI_Command(const char [4], <unresolved overloaded function type>)"
This illustrates the correct syntax:
class CLI;
struct CLI_Command
{
CLI_Command(char* s, void (CLI::*h)(void))
{
command_string = s;
handler = h;
}
char* command_string;
void (CLI::*handler)(void);
void raise( CLI* the_cli ) { return (the_cli->*handler)(); }
};
class CLI
{
public:
CLI();
private:
static CLI_Command cli_table[NO_CLI_COMMANDS];
void handler1(){};
void handler2(){};
};
CLI::CLI_Command cli_table[NO_CLI_COMMANDS] = {
{ "Command1", &CLI::handler1 },
{ "Command2", &CLI::handler2 }
};
Names of member functions do not decay to pointer-to-member. You must use & explicitly, and a qualified name, when creating a pointer-to-member.
In addition to other answers, another option is to use std::function together with std::bind():
struct CLI_Command{
...
std::function<void> handler;
};
class CLI {
...
CLI_Command cli_table[NO_CLI_COMMANDS] = {
{ "Command1", std::bind(&CLI::handler1, this) },
{ "Command2", std::bind(&CLI::handler2, this) }
};
void handler1(){};
void handler2(){};
};
void handler1(){}
void handler2(){}
are member functions of CLI. The correct way to "address to" them is &CLI::handler1 and not handler1. However then, they won't be accepted by void (*h)(void), which would need to be changed to void (CLI::*h)(void). But that is probably not what you want.
Maybe consider reading about std::function for type erasure, or make your handler1/handler2 static.
You should use the syntax for a pointer to class member instead of the syntax for a loose function pointer.
class CLI;
struct CLI_Command{
CLI_Command(char* s, void (CLI::*h)(void)){
command_string = s;
handler = h;
}
char* command_string;
void (CLI::*handler)(void);
};
In addition, make sure you call the function through the pointer of the current CLI class;
void CLI::process(char *cmd) {
CLI_Command command* = /* lookup the command */
this->(command->handle)();
}
To get it working, make your methods static
static void handler1(){};
static void handler2(){};
Whatever consequences (read here please, for more detailed info) this will have :-( .
Related
I know this sounds like a weird thing to want, but I guess I have my reasons. I can do:
#include <string>
#include <iostream>
struct Shark
{
template <auto* static_ptr_to_self>
void whatIsMyAddress() {
std::cout << std::string("My address is ") + std::to_string((uintptr_t)static_ptr_to_self);
}
};
Shark shark;
int main()
{
shark.whatIsMyAddress<&shark>();
return 0;
}
But is there a way to achieve something like this without passing in the pointer to the function? For example can the object itself hold a pointer, resolved at compile-time, not a runtime pointer, to itself? My instinct is no because when the object is created it hasn't been declared yet. But is there some way to achieve this? If there isn't through passing the pointer as a template argument then is there a way with a constexpr member pointer?
Edit: Just to explain my question better:
struct ResourceMngr
{
void IveBeenCopied(const Handle& handle);
int referenceCountTracker[256];
};
struct Handle
{
int ID;
Handle(const Handle& other) { dynamicPtrToManager->IveBeenCopied(*this); }
ResourceMngr* dynamicPtrToManager;
};
void ResourceMngr::IveBeenCopied(const Handle& handle)
{
++referenceCountTracker[handle.ID];
}
So each handle has a pointer to let whatever is managing the resource know of 'stuff'. So now I can get rid of the pointer in handle, which has the effect of eliminating the pointer lookup (because it's constexpr) and also eliminating a pointer from each handle, by doing this:
struct ResourceMngr
{
void IveBeenCopied(const auto& handle);
int referenceCountTracker[256];
};
template <auto* static_ptr_to_manager>
struct Handle
{
int ID;
Handle() {}
Handle(const Handle& other) { static_ptr_to_manager->IveBeenCopied(*this); }
//ResourceMngr* dynamicPtrToManager; // No longer needed
};
void ResourceMngr::IveBeenCopied(const auto& handle) { ++referenceCountTracker[handle.ID]; }
ResourceMngr bufferManager;
int main()
{
Handle<&bufferManager> handle1;
Handle<&bufferManager> handle2 = handle1;
// No pointer members in each handle,
// no runtime lookup of pointers
}
And I can get a handle from a resource manager like:
template <auto* static_ptr_to_manager>
struct Handle
{
int ID;
Handle() {}
Handle(const Handle& other) {
//static_ptr_to_manager->IveBeenCopied(*this);
}
};
struct ResourceMngr
{
template <auto* static_ptr_to_self_type>
Handle<static_ptr_to_self_type> getHandleToAResourceOrObject()
{
return Handle<static_ptr_to_self_type>();
}
};
ResourceMngr bufferManager;
int main()
{
Handle<&bufferManager> handle = bufferManager.getHandleToAResourceOrObject<&bufferManager>();
// Here I have to specify in the function call
//which manager I'm referring to.
// The bufferManager couldn't use the this pointer as
//it's not constexpr and can't be used
// in template arguments
}
What's the proper syntax to accomplish this? The idea is that some object of any class could store a lambda expression in class GuiButton, and then later that call that lambda expression with access to its own local variables.
It should be noted that my platform (Arduino) does NOT support the functional header.
The code I've written to try to express this idea (which does not compile due to the lambda expressions not having access to members of ExampleScreen):
struct GuiButton {
uint8_t x; //coordinates for displaying this GUI element
uint8_t y;
GuiButton(uint8_t _x, uint8_t _y, void (*_callback)()) :
x(_x),
y(_y),
callback(_callback)
{};
virtual void draw(bool _highlight);
public:
void (*callback)(); //to be executed BY THE PARENT OBJECT when this element is clicked
};
struct GuiTextButton: public GuiButton {
char* text; //text to display in this GUI element
GuiTextButton(uint8_t _x, uint8_t _y, char* _text, void (*_callback)()) :
GuiButton(_x, _y, _callback),
text(_text)
{};
void draw(bool _highlight);
};
class ExampleScreen{
private:
GuiButton** buttonPtr;
uint8_t buttonCount;
uint8_t selectedButton;
bool proc1Active;
bool proc2Active;
public:
ExampleScreen() :
buttonPtr(NULL),
buttonCount(0),
selectedButton(0),
proc1Active(false),
proc2Active(false)
{
//different derived classes of GuiScreen shall have different constructors to define
//their visual and functional elements
buttonPtr = new GuiButton* [2];
buttonCount = 2;
{
char text[] = "Button1";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc1Active = ~proc1Active;
});
buttonPtr[0] = _thisPtr;
}
{
char text[] = "Button2";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc2Active = ~proc2Active;
});
buttonPtr[2] = _thisPtr;
}
};
void click() {
void (*callback)() = (buttonPtr[selectedButton]->callback);
callback();
};
};
int main() {
ExampleScreen gui;
gui.click();
};
Something along these lines:
class GuiButton {
GuiButton(void (*_callback)(void*), void* _context)
: callback(_callback), context(_context) {}
// Invoke the callback as callback(context)
void (*callback)(void*);
void* context;
};
// In ExampleScreen
new GuiButton([](void* context) {
auto self = static_cast<ExampleScreen*>(context);
self->proc1Active = ~self->proc1Active;
}, this);
Per the comments on your discussion you can't use the functional header which rules out the easy solutions (namely having the callback be a std::function and either capturing the context or using std::bind to bind it.
However, I think you can still do what you want. Make the type of callback be a struct like:
struct CallbackData {
void (*callback)(ExampleScreen*);
ExampleScreen* context;
// obvious constructor here...
}
Then you can call the callback like so:
callback_data.callback(callback_data.context);
And you pass it to the GuiButton constructor like:
new GuiTextButton(5,0,text,CallbackData([](ExampleScreen* e) { ... }, this));
Perhaps a nicer option is to use a functor. To do that you'd create a class like so:
class GuiButtonCallback {
public:
GuiButtonCallback(ExampleScreen* context) : context_(context) {}
void operator() {
context->proc1Active = ~context->proc1Active;
}
private:
ExampleScreen* context_;
};
And then you can construct things like so:
new GuiTextButton(5 , 0, text, GuiButtonCallback(this));
I am doing a small project using arduino and I need to use an array of methods.
I've tried doing what I would normally do in C# / Java but that didn't work. I went online and tried many different examples and I kept getting lead to the same error message.
class ColourSensor{
public:
void (*routine[3])() = {
routine0,
routine1,
routine2
};
void routine0();
void routine1();
void routine2();
};
When I compile I get the following error:
cannot convert 'ColourSensor::routine0' from type 'void (ColourSensor::)()' to type 'void (*)()'
Things get complicated because they are methods. A method has an implicit hidden this parameter, so it's a different type than a free functions.
This is the correct syntax:
class ColourSensor
{
public:
using Routine = void (ColourSensor::*)();
Routine routines[3] = {
&ColourSensor::routine0,
&ColourSensor::routine1,
&ColourSensor::routine2,
};
void routine0();
void routine1();
void routine2();
void test()
{
// calling syntax:
(this->*routines[0])();
}
};
An alternative which simplifies the calling syntax using non-capturing lambdas (which can decay to function pointer):
class ColourSensor
{
public:
using Routine = void (*)(ColourSensor*);
Routine routines[3] = {
[](ColourSensor* cs) { return cs->routine0(); },
[](ColourSensor* cs) { return cs->routine1(); },
[](ColourSensor* cs) { return cs->routine2(); }
};
void routine0();
void routine1();
void routine2();
void test()
{
// simpler calling syntax
routines[0](this);
}
};
Going one step further (and off the rails), if you know you always use this object to call the methods you need to capture this in lambda. The problem now is that capturing lambdas can't decay to function pointers and since every lambda is a different type you can't store them in an array. The usual solution in C++ is type erasure with std::function. Unfortunately arduino C++ environment doesn't have the C++ standard library (because of the size constraints). For reference, this is how it would have looked (and since we are using the standard library, we use std::array):
/// !! not working in Arduino !!
#include <functional>
#include <array>
class ColourSensor
{
public:
std::array<std::function<void(void)>, 3> routines = {
[this]() { return this->routine0(); },
[this]() { return this->routine1(); },
[this]() { return this->routine2(); }
};
void routine0();
void routine1();
void routine2();
void test()
{
// simple calling syntax
routines[0]();
}
};
There is a workaround for this. And although it's a bit of work to setup, it's actually faster than the std::function because we don't use type erasure:
class ColourSensor;
class Routine
{
private:
using R = void (ColourSensor::*)();
R routine_;
ColourSensor* calling_obj_;
public:
Routine(R routine, ColourSensor* calling_obj)
: routine_{routine}, calling_obj_{calling_obj}
{}
void operator()();
};
class ColourSensor
{
public:
Routine routines[3] = {
Routine{&ColourSensor::routine0, this},
Routine{&ColourSensor::routine1, this},
Routine{&ColourSensor::routine2, this}
};
void routine0();
void routine1();
void routine2();
void test()
{
// simple calling syntax
routines[0]();
}
};
void Routine::operator()() { return (calling_obj_->*routine_)(); }
If however your routines don't use the state of the ColourSensor, than you can make them static functions:
class ColourSensor
{
public:
using Routine = void (*)();
Routine routines[3] = {
routine0,
routine1,
routine2,
};
static void routine0();
static void routine1();
static void routine2();
void test()
{
routines[0]();
}
};
class IEngine: public ICoreObject
{
private:
Network *_Network;
bool _Process;
public:
IEngine();
~IEngine();
void Initial(...);
void StartServer(unsigned short port);
bool Process();
void StopProcess();
void StartProcess();
friend void ShellCode(int id,struct NE_Bin var);
};
Why i cant use _Network from ShellCode ?
this is definition of ShellCode function
void ShellCode(int id,struct NE_Bin var) //функция-друг
{
std::cout<<"ShellFunc Delegated"<<std::endl;
var.data = (void *)"T";
var.length = 1;
//_Network->SendMessageW(id, var);
}
Im trying to get to the _Network class and i get errors.
IEngine has ShellCode as a friend. That means you can access private **members of an IEngine object. _Network is just a variable in your context, not bound to anything.
Something like this would work:
void ShellCode(int id,struct NE_Bin var, IEngine* pEngine)
{
std::cout<<"ShellFunc Delegated"<<std::endl;
var.data = (void *)"T";
var.length = 1;
pEngine->_Network->SendMessageW(id, var);
}
but you need to pass the IEngine as parameter:
IEngine* pEngine /*initialize it here*/;
ShellCode(0, NE_Bin(), pEngine);
or you can use a global instance inside the method (if you have one).
Well you'd need an instance of of IEngine as a parameter to access it's member variable...
I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.