I have the class object Chat *p, and I'm looking to run the method Foo(int num) on it (usually running by p -> Foo(3) for example).
I've written this code :
std::thread F(&Chat::Foo, 4);
though, it does not compile to me, and I also see theres an error, since I was not able to put p -> Foo into it (instead of &Chat::Foo...)
How can I run this code correctly?
Thanks!
The answer from how object methods actually work. When you call p->foo(3) what the compiler translates it to, roughly speaking, is Chat::foo(p, 3). P is always passed as a hidden parameter in any call to a function. C++ doesn't show you this and you can't actually call Chat::foo(p, 3), this just isn't allowed, but it roughly how things work in reality.
The variable this that is available in any member function is just the address that is passed in as the hidden first parameter and any member variables that you access in the function reference the hidden first parameter. So... what you need to do in order to call any member function as the starting point to a thread, is pass the pointer to the object as it's first parameter. std::thread F(&Chat::Foo, p, 4); will, I believe, start the thread properly.
Related
I made the following method in a C++/CLI project:
void GetSessionData(CDROM_TOC_SESSION_DATA& data)
{
auto state = CDROM_TOC_SESSION_DATA{};
// ...
data = state;
}
Then I use it like this in another method:
CDROM_TOC_SESSION_DATA data;
GetSessionData(data);
// do something with data
It does work, returned data is not garbage, however there's something I don't understand.
Question:
C++ is supposed to clean up state when it has exitted its scope, so data is a copy of state, correct ?
And in what exactly it is different from the following you see on many examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data); // signature should be GetSession(CDROM_TOC_SESSION_DATA *data)
Which one makes more sense to use or is the right way ?
Reference:
CDROM_TOC_SESSION_DATA
Using a reference vs a pointer for an out parameter is really more of a matter of style. Both function equally well, but some people feel that the explicit & when calling a function makes it more clear that the function may modify the parameter it was passed.
i.e.
doAThing(someObject);
// It's not clear that doAThing accepts a reference and
// therefore may modify someObject
vs
doAThing(&someObject);
// It's clear that doAThing accepts a pointer and it's
// therefore possible for it to modify someOjbect
Note that 99% of the time the correct way to return a class/struct type is to just return it. i.e.:
MyType getObject()
{
MyType object{};
// ...
return object;
}
Called as
auto obj = getObject();
In the specific case of CDROM_TOC_SESSION_DATA it likely makes sense to use an out parameter, since the class contains a flexible array member. That means that the parameter is almost certainly a reference/pointer to the beginning of some memory buffer that's larger than sizeof(CDROM_TOC_SESSION_DATA), and so must be handled in a somewhat peculiar way.
C++ is supposed to clean up state when it has exitted its scope, so
data is a copy of state, correct ?
In the first example, the statement
data = state
presumably copies the value of state into local variable data, which is a reference to the same object that is identified by data in the caller's scope (because those are the chosen names -- they don't have to match). I say "presumably" because in principle, an overridden assignment operator could do something else entirely. In any library you would actually want to use, you can assume that the assignment operator does something sensible, but it may be important to know the details, so you should check.
The lifetimes of local variables data and state end when the method exits. They will be cleaned up at that point, and no attempt may be made to access them thereafter. None of that affects the caller's data object.
And in what exactly it is different from the following you see on many
examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data);
Not much. Here the caller passes a pointer instead of a reference. GetSessionData must be declared appropriately for that, and its implementation must explicitly dereference the pointer to access the caller's data object, but the general idea is the same for most intents and purposes. Pointer and reference are similar mechanisms for indirect access.
Which one makes more sense to use or is the right way ?
It depends. Passing a reference is generally a bit more idiomatic in C++, and it has the advantage that the method does not have to worry about receiving a null or invalid pointer. On the other hand, passing a pointer is necessary if the function has C linkage, or if you need to accommodate the possibility of receiving a null pointer.
i just wanted to know what is the best way to pass a local variable to a function.
void check2 (int* var2){
*var2=7;
}
void check1 (int& var){
var=6;
}
int main()
{
int var;
int* var2=new int;
check1(var);
check2(var2);
delete var2;
return 0;
}
In check1, I pass the variable using a reference. As I am passing a local variable to the function check1, wouldn't it get out of scope once main terminates and there would be no variable anymore?
I found a couple of examples where the operator new is used to allocate memory and return a pointer which is then passed to the function. Is this a better way to do the same task as the variable doesn't get erased?
[What is the] Best way to pass local variable to function
Depends on why you pass the variable, and what you do with it.
Passing a reference implies that the function does not take ownership of the object, and the function clearly doesn't take ownership, so that's appropriate. Passing a bare pointer is ambiguous about change of ownership so in this case, reference is better.
As I am passing a local variable to the function check1, wouldn't it get out of scope once main terminates and there would be no variable anymore?
Correct. However, whether the object exists after main returns, is mostly orthogonal to the question of how to pass the object to a function within main.
Also do realize that after main returns, the whole program is about to terminate. The only situation where you'd still need an object to exist at that point, is if that object is depended on by a destructor of another object that has static storage.
I found a couple of examples where the operator new is used to allocate memory and return a pointer which is then passed to the function. Is this a better way to do the same task as the variable doesn't get erased?
If you do need to create an object in main, but need that object to exist after main has finished, then dynamic allocation is one way to achieve that. Static storage might be an alternative.
In this example however, you delete the object in main, so it gets destroyed just like the local variable does, so in this case, the dynamic allocation offers no advantage.
I have a simple question that I am not 100% sure on.
Let us say I have a Entity class, that handles objects on the screen. Let us say the Entity class has two float variables, 'x' and 'y' (aka coordinates). Also let us say the entity I am passing has already been declared and is in memory.
I have another class that handles camera movement. It requires an entity to center on. The entity that it is centered on can changed, so I need to use a pointer here I believe. The only thing I do here is grab the X and Y variables when needed. Nothing is changed here.
I've defined it as
void StarField::ChangeFollowEntity(Entity* newFollowEntity) {
followEntity = newFollowEntity;
}
where followEntity is also an Entity class. I would call ChangeFollowEntity(..) to change the entity. Is this actually correct?
I've also seen however this:
void StarField::ChangeFollowEntity(Entity newFollowEntity) {
followEntity = &newFollowEntity;
}
In both cases followEntity is defined as Entity* followEntity; .. What does the second example exactly do here? From what I understand, & would typically be used as a reference type. Maybe it is incorrect to do to begin with.
I am pretty sure I shouldn't be using a reference in this case because the followEntity changes, which references I believe cannot change and must be defined.
So my question is, is my first example correct and the right way to do it? What does the second example do exactly?
In your second version ::
void StarField::ChangeFollowEntity(Entity newFollowEntity) {
followEntity = &newFollowEntity;
}
You pass the newFollowEntity by value, so when your function is called from main or from where ever! A copy of the object is made (using the copy constructor) and sent to the function ChangeFollowEntity, and after the completion of the execution of the function, your followEntity has the address of the COPY of the object, which gets destroyed after the completion of the function call, so your pointer followEntity is left dangling, which is undefined behavior if you access any entity using the followEntity
First is the correct way to do it!!
The second example does the following:
When the function is called a new Entity object newFollowEntiry
is created and whatever is passed into the function is used to
construct it
Then an address of that local stack based object is taken and
assigned to followEntiry to be stored presumably.
When the function execution is complete newFollowEntiry is destroyed
The folowEntity pointer is now pointing at a location in stack where
there is not Entity object anymore.
BUG
What does the second example exactly do here?
Your second example creates a Entity newFollowEntity which only exists for the duration of that function call.
The address of that variable is stored, and then the variable is destroyed, leaving a dangling pointer.
That's bad.
I am pretty sure I shouldn't be using a reference in this case because the followEntity changes, which references I believe cannot change
You can use a reference in this case. A referenced object can be changed - you are probably recalling that a reference cannot be reassigned.
So, I'm using the FMOD api and it really is a C api.
Not that that's bad or anything. Its just it doesn't interface well with C++ code.
For example, using
FMOD_Channel_SetCallback( channel, callbackFunc ) ;
It wants a C-style function for callbackFunc, but I want to pass it a member function of a class.
I ended up using the Win32 trick for this, making the member function static. It then works as a callback into FMOD.
Now I have to hack apart my code to make some of the members static, just to account for FMOD's C-ness.
I wonder if its possible in FMOD or if there's a work around to link up the callback to a specific C++ object's instance member function (not a static function). It would be much smoother.
You cannot directly pass a member function. A member function has the implicit parameter this and C functions don't.
You'll need to create a trampoline (not sure the signature of the callback, so just doing something random here).
extern "C" int fmod_callback( ... args ...)
{
return object->member();
}
One issue is where does that object pointer come from. Hopefully, fmod gives you a generic context value that will be provided to you when your callback is made (you can then pass in the object pointer).
If not, you'll just need to make it a global to access it.
I guess it supposed to work like this:
You can assign some user data to channel by calling FMOD_Channel_SetUserData. This user data should be a pointer to your C++ object that handles events.
Then you should write C-style callback that extracts that object by calling FMOD_Channel_GetUserData and then calls your C++ instance method on that object.
There is a non-portable, and pretty hackish solution that has the advantage of at least being thread-safe, which the "trampoline" methods are not.
You can generate the actual function machine code on the fly. The basic idea is that you have a template for your call-back function that takes an object pointer and a member-function pointer and gives you a block of heap memory that you can pass to the library as a C call-back function, that will, when called, turn around and call the member function on that object.
It's messy, and you'll have to provide an implementation for any new platform (any time the calling convention changes), but it works, is thread-safe. (Of course you'll also have to watch out for DEP). The other thread-safe solution is to resort to thread-local storage (assuming that you know the call-back will happen on the same thread as the call you made).
See http://www.codeproject.com/KB/cpp/GenericThunks.aspx for an example of how you could go about generating thunks.
Using only a function pointer (and no additional separate object pointer) for a C callback is a broken design, in my humble opinion.
If the function were, instead, FMOD_Channel_SetCallback(channel, callbackFunc, callbackObj), then your static method just takes an instance of the object, then calls callbackObj->func() (which obviously can be non-static).
you need to use a trampoline and store the pointer to the object you want to get the member function called on in a global or static variable, i.e.
Object *x;
void callback_trampoline() { x->foobar(); }
...
FMOD_Channel_SetCallback(CHANNEL, callback_trampoline);
io_iterator_t enumerator;
kern_return_t result;
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
serviceMatchingCallback,
(void *)0x1234,
& enumerator );
serviceMatchingCallback((void *)0x1234, enumerator);
if i declare serviceMatchinCallback as static then it works, but i do not want it to be static. Is there a way to pass it a non-static callback function?
Thank you
The prototype for IOServiceMatchingCallback is not compatible with a non-static class method (and technically is not compatible with a static class method either), so you are not going to be able to use that.
But luckily IOServiceAddMatchingNotification supports a context pointer (or as they call it, a refCon) which will allow you to create a thunk that does not rely on global data.
You need to define a callback with compatible linkage (i.e. extern "C"). This function will cast your refCon to your object pointer and then forward the call to your instance method:
extern "C"
void io_callback(void *refcon, io_iterator_t iterator)
{
myclass *c = static_cast<myclass *>(refcon);
c->real_callback(iterator);
}
Then, when you call IOServiceAddMatchingNotification, make sure to pass a pointer to your object for refCon (here I'm assuming you call IOServiceAddMatchingNotification from a member function and you have a this pointer):
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
serviceMatchingCallback,
this,
&enumerator );
You could keep it static, but use the userdata to store the this pointer in addition to whatever other userdata you want (by packing them into a structure, for example) and then call an object-specific callback from the static version by calling this->someCallback (where this is the pointer stored in the userdata, of course).
Not directly.
The non-static function pointer (known as a member function pointer) has a hidden 'this' parameter so the types don't match. The static function has no 'this' pointer.
To get around this, you need to be able to pass in a user data item which is the 'this' pointer of the object you want to use as a callback. Then, specify a static member that is passed the user data, converts it to a pointer to the class object and calls the non-static member on it.
Looking at the code you've posted, it's hard to tell if there is a user data object, possibly the last-but=one parameter.
No, a non-static member would expect an object, and the caller (call-backer) does not have and will not provide one.
No. Non-static methods need an object to operate on. If you were to merely pass the method you would also need some way to tell the function which object to call the method on.
A non-static function has an implicit this parameter, and thus would have the wrong signature for the callback.
Sorry, no easy way to avoid the jump island.
if you put this line in your constructor (or in any instance method) then you should be able to do this.instanceMethod() to refer to the instance method.
EDIT
I just noticed you are using the user space IOKit API, not the kext side, which makes this post irrelevant.
Assuming you are working within the OS X kernel, you actually can do this.
You can use the OSMemberFunctionCast macro to convert a member function pointer to a plain C function pointer, do note that it should be called with the first argument pointing to an instance of the class, eg.
IOServiceMatchingCallback mycb = OSMemberFunctionCast(IOServiceMatchingCallback,
&myclassinstance, &MyClass::cb_method);
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
mycb,
&myclassinstance,
&enumerator);