After I moved some OpenGL code from main function to a new class I had the following error on the following row:
glutDisplayFunc(OnDisplay);
error C3867: 'Room::OnDisplay': function call missing argument list; use '&Room::OnDisplay' to create a pointer to member
What was my fault ?
glutDisplayFunc expects a void (*func)(void), but you're passing in a void (Room::*func)(void).
Since class methods receive an implicit this parameter, their pointer types are fundamentally different than regular function pointers. There's no conversion possible between them.
All you can do is make OnDisplay a static member of Room. From there you can forward the call to a member function of a concrete Room instance (since there is by design only one glut display callback and you migrated from procedural code, I presume you have only a single Room object somewhere).
glutDisplayFunc just takes pointer to the function. When moved OnDisplay to the class, you will also pass the hidden argument this to glutDisplayFunc when actually get called.
One possible solution is to make OnDisplay as a static method.
Related
I'm currently learning game development with c++ in Unreal Engine and I came across the function that takes a function pointer as an input:
InputHandle->BindAction("Grab",IE_Pressed, this, &UGrabber::Grab);
From basic C++ I know that in passing a function pointer as an attribute (UGrabber::Grab) - & is optional, however UEngine complains with the following error code if I omit the &:
error C3867: 'UGrabber::Grab': non-standard syntax; use '&' to create a pointer to member
Could someone explain why?
BindAction function declaration looks like this:
FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename FInputActionHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr Func )
The BindAction function makes use of a Dynamic Multicast Delegate.
They are one of Unreal's ways of having callback functions. In this case, they rely not just on calling a function, but calling a specific object's function. This is why you need to bass the third parameter (in this example, the parameter is this).
What it's saying is, when the input action is IE_Pressed, call the UGrabber function Grab on object this (this has to be a UGrabber instance of course). This is why it's a pointer to the method. It actually utilizes Unreal's reflection system to find the method on the object. So the this object needs to be UObject, otherwise you can't call a funciton on an object by name in C++.
For more info on this, search for "unreal delegates" and "unreal reflection" in your search engine of choice. Using them is quite easy, and it's not necessary to understand the reflection system to reliably use them. Just don't forget to bind and unbind at the appropriate times.
p.s. You can get quite in depth in this subject of callbacks you want. There are other delegate types that don't rely on reflection, for example non-dynamic delegates, that can bind to lambda functions, and or a more familiar if you're coming from a pure C++ background, where commonly a void* opaque is used, expected to be cast to the needed class pointer.
In my Qt application I wish to be able to add a tab to a non-static QTabWidget when the user presses a shortcut. Normally I would implement it like this:
File.addAction("Settings", openSettings, Qt::ALT + Qt::Key_S);
where File is a QTabWidget and openSettings is a static method. The only issue with that is that it only works for static methods, and the issue with that is that I can't access a non-static variable in a static method. As such I figured that since Qt asks for the function to be a static function I can instantiate a static std::function<> object as such:
static std::function<void(void)> openSettings_ = []() { openSettings; };
and call it as such
File.addAction("Settings", openSettings_, Qt::ALT + Qt::Key_S);
The issue with this is that it generates the error:
Error: invalid use of non-static member function 'void window::openSettings()'
My reasoning for this is that I am familiar with C and assumed that what Qt calls a functor is almost the same as a function pointer that pretty much is an object. As such, I assumed that if I were to instantiate a static object of type std::function that pointed to / executed a non-static function I would get around this issue, which is clearly not the case. How would I go about doing this, seeing as my current thought process is wrong?
First, the immediate error is raised because you're not actually calling the function. You must call it: openSettings();.
However, this won't work. openSettings is non-static member function. All such normal member functions take an implicit this pointer to the object on which they're being invoked. This means that one cannot directly invoke the openSettings function without an object on which to invoke it. But this is not captured by the lambda you've written, meaning there's no such object.
This can be fixed by capturing this in the lambda, such as auto openSettings_ = [this]() { this->openSettings(); };
But on the other hand, this function is acting like a slot. You should attach the signal you're interested in directly to the signal using the standard signal/slot syntax, rather than writing the separate functor. That would be something like this.
File.addAction("Settings", this, &(decltype(*this))::openSettings, Qt::ALT + Qt::Key_S);
(Note that I'm using decltype because I'm not sure what type *this is. You can substitute with the name of the class.)
Background
The title probably sounds confusing, so let me explain. First of all, here is a minimal version of my implementation, so you can follow along with the concepts more easily. If you've seen some of Sean Parent's talks, you'll know he came up with a way to abstract polymorphism, allowing code such as this:
std::vector<Drawable> figures{Circle{}, Square{}};
for (auto &&figure : figures) {draw(figure);}
Notice that there are no pointers or anything. Calling draw on a Drawable will call the appropriate draw function on the contained object without the type of the object being easily accessible. One major downside to this is that similar classes to Drawable have to be written for each task. I'm trying to abstract this a bit so that the function does not have to be known by the class. My current solution is as follows:
std::vector<Applicator<Draw>> figures{Circle{}, Square{}};
for (auto &&figure : figures) {figure.apply(Draw{});}
Here, Draw is a functor with an operator()(Circle) and opeator()(Square), or a generic version. In this way, this is also sort of a visitor pattern implementation. If you wanted to also, say, print the name of each figure, you could do Applicator<Draw, PrintName>. When calling apply, the desired function is chosen.
My implementation works by passing a boost::variant of the callable types to the virtual function and having it visit that variant and call the function within. Overall, I would say this implementation is acceptable, but I haven't yet thought much about allowing any number of parameters or a return type, let alone ones that differ from function to function.
Question
I spent days trying to think of a way to have this work without making Applicator a template. Ideally, the use would be more similar to this. For the sake of simplicity, assume the functions called must have the signature void(ObjectType).
//For added type strictness, I could make this Applicator<Figure> and have
//using Figure<struct Circle> = Circle; etc
std::vector<Applicator> figures{Circle{}, Square{}};
for (auto &&figure : figures) {figure.apply(Draw{});} //or .apply(draw); if I can
The problem usually comes down to the fact that the type of the object can only be obtained within a function called on it. Internally, the class uses virtual functions, which means no templates. When apply is called, here's what happens (identical to Sean's talks):
The internal base class's apply is called on a pointer to the base class with the runtime type of a derived class.
The call is dispatched to the derived class, which knows the type of the stored object.
So by the time I have the object, the function to call must be reduced to a single type known within the class that both knows which function to call and takes the object. I cannot for the life of me come up with a way to do this.
Attempts
Here are a couple of failed attempts so you can see why I find this difficult:
The premise for both of the first two is to have a type that holds a function call minus the unknown first argument (the stored object). This would need to at least be templated on the type of the callable object. By using Sean Parent's technique, it's easy enough to make a FunctionCall<F> class that can be stored in a GenericFunctionCall, much like a Circle in a Figure. This GenericFunctionCall can be passed into the virtual function, whereas the other cannot.
Attempt 1
apply() is called with a known callable object type.
The type of the callable object is used to create a FunctionCall<Type> and store it as a type-erased GenericFunctionCall.
This GenericFunctionCall object is passed to the virtual apply function.
The derived class gets the call object and has the object to be used as the first argument available.
For the same reason of virtual functions not being allowed to be templates, the GenericFunctionCall could call the necessary function on the right FunctionCall<Type>, but not forward the first (stored object) argument.
Attempt 2
As a continuation of attempt 1:
In order to pass the stored object into the function called on the GenericFunctionCall, the stored object could be type-erased into a GenericObject.
One of two things would be possible:
A function is called and given a proper FunctionCall<Type>, but has a GenericObject to give to it, with the type unknown outside of a function called on it. Recall that the function cannot be templated on the function call type.
A function is called and given a proper T representing the stored object, but has a GenericFunctionCall to extract the right function call type from. We're back where we started in the derived class's apply function.
Attempt 3
Take the known type of a callable object when calling apply and use it to make something that stores a function that it can call with a known stored object type (like std::function).
Type-erase that into a boost::any and pass it to the virtual function.
Cast it back to the appropriate type when the stored object type is known in the derived class and then pass the object in.
Realize that this whole approach requires the stored object type to be known when calling apply.
Are there any bright ideas out there for how to turn this class into one that doesn't need the template arguments, but can rather take any callable object and call it with the stored object?
P.S. I'm open for suggestions on better names than Applicator and apply.
This is not possible. Consider a program composed of three translation units:
// tu1.cpp
void populate(std::vector<Applicator>& figures) {
figures.push_back(Circle{});
figures.push_back(Square{});
}
// tu2.cpp
void draw(std::vector<Applicator>& figures) {
for (auto &&figure : figures) { figure.apply(Draw{}); }
}
// tu3.cpp
void combine() {
std::vector<Applicator>& figures;
populate(figures);
draw(figures);
}
It must be possible for each TU to be translated separately, indeed in causal isolation. But this means that at no point is there a compiler that simultaneously has access to Draw and to Circle, so code for Draw to call Circle::draw can never be generated.
I'm having a problem with function pointers and nothing I found on the net helped me to solve this problem.
I have a function from a C API which take a pointer of a void function :
extern int APIFunction(int, void (*func)(int));
I have a class with the function I would like to put when I call the API function.
class MyClass
{
public:
void myFunction(int status, otherAPi arguments...);
};
Then, I created a pointer to my member function and created a new instance of my class
typedef void (MyClass::*MyClassFunctionPointer)(int stat, otherAPi arguments...);
MyClassFunctionPointer fctPointer= &MyClass::myFunction;
LicenseSecurity instance;
I get an error when I try to call my APi function with the function pointer I created:
int stat = APIFunction(5, fctPointer ); // -> error 1
int stat = APIFunction(5, instance.*fctPointer ); // -> error 2
I got errors respectively in the first and second case:
E2034 Impossible to convert 'void (MyClass::*)(int, otherAPITypes...)' into 'void (*) (int, otherAPITypes...)'
E2342 Bad type correspondence in the parameter 'func' ('void (*)(int, otherAPITypes...)' desired, 'void(int, otherAPITypes...)' obtained)
I don't have access to the API function so I can't modify it. To summary the problem: how How to get a "simple" C function pointer to put in argument of a function from a member function of my class?
Thanks
Unfortunately, you can't. Sorry.
Ideally, your API would accept something like std::function that would allow you to wrap free functions or member functions. But if you can't modify the API, then you have no choice but to provide a free function.
You can't get a "simple" function pointer to a non-static member function because the function requires a this pointer when called. If you were to create a function pointer like that then when the function was called there would be no this pointer for it to reference.
With an ancient C API like that, you unfortunately don't have any way to do this.
What you have to do is make a static or non-member function to take the callback, and then figure out which instance of the object to call the member on. Some C APIs allow a user data to be passed to the callback, and in that case you use that to store the this pointer in question. If that's not an option you can use a global or singleton object and only allow a single such callback to be registered.
You can declare the callback as either a standalone function or as a static method of the class. The tricky part is accessing a class instance pointer inside the callback.
Ideally, a well-designed API allows you to specify a user-defined value to callbacks. That allows you to easily pass in a class instance and access it directly inside the callback. But it sounds like you are not working with such an API, so you need to use a workaround.
If you have only 1 class instance being used with the API at a time, you can store the instance pointer into a global variable, and have the callback use the global variable to access the instance.
But if you have multiple class instances being used at the same time, you are looking for a thunking solution, similar to the VCL's MakeObjectInstance() function, which allows TWndMethod-signatured class methods to be used as Win32 window procedure callbacks. Essentially, a block of executable memory is dynamically allocated, stub assembler code is written into the block, and the instance pointer and class method pointer are stored in the block as well. The block is then passed to the API as if it were a function pointer. When the API calls the "function", the stub code gets executed, which has to manipulate the call stack and CPU registers to call the stored class method pointer passing the stored instance pointer as its hidden this parameter, while preserving the semantics of other parameters, the call stack, function result, etc.
Nothing in C++ really accomplishes that kind of thunking natively. It is not difficult to implement manually, but it is not trivial either (have a look at the source code for MakeObjectInstance() in the VCL's Classes.pas source file). The hardest part is coming up with the necessary stub code that matches the semantics of your particular class method's signature.
I'm currently working with Qt and a graphics engine and during the init of the QGLWidget instance I need to pass a few function pointers to my engine.
The function looking for callbacks is:
virtual void Buffer::CreateCustom( byte* getsize, byte* makecurrent)
Qt provides a makeCurrent function however it is neither byte* nor static.
I could write a tiny wrapper function like so:
void _stdcall MakeCurrent(void)
{
QGLContext::makeCurrent();
}
But its only meant to be called from within an instance of GLWidget. I tried to create a class member wrapper function like so:
void _stdcall LEWidget::leMakeCurrent(void)
{
makeCurrent();
}
But you can only provide function pointers on static member functions. If I do that I get the following error:
error C2352: 'QGLWidget::makeCurrent' : illegal call of non-static member function. A nonstatic member reference must be relative to a specific object.
See this question, I think it is pretty much what you want to do:
How do I implement a callback in C++?
You can't. That's what std::function exists for. You need to either change your interface to use std::function, get lucky and find some kind of void* context argument, or give up.
This is because it is impossible to tell(from the compiler's POV) which this pointer should be pass into that function when that callback is called. If you really really want to pass in a pointer, you'll have to use assembly.