I have a hooking library that i am porting to C++, the only problem i have its that i need a void pointer to client function, and i cant get a raw pointer of any function member, so for now it only works with static functions. This enforce me to make a singleton pattern which i dont want to.
Here is a snippet of the current problem i am facing for making an class that prints data regarding functions that are hooked:
class SpyLib
{
private:
HookLib hooklib;
std::vector<SpyRecord> records;
SpyRecord findRecord(int id);
public:
//Member function to callback after the hook
void spyer(void* register_context, int hookid);
};
Since i cant get the address of spyer function i need to declare it "static" that makes me declare the findRecord as well for finding data regarding the hook process. Since findRecord use "records" vector, that needs to be static too and so on. In the end i am dealing with a static class and forced to use a singleton pattern.
Question is: is there any method besides messing with vtables for finding the VA of a member function? if not, then how detour library from microsoft does it?.
Thanks.
You can always bypass the problem by delegating function call to wrapper non-member function:
class Pars
{
public:
SpyLib* spyLibPtr;
void* register_context;
int hookid;
};
void call_spyer(void* voidPtr)
{
Pars* parsPtr = reinterpret_cast<Pars*>(voidPtr);
parsPtr->spyLibPtr->spyer(parsPtr->register_context,parsPtr->hookid);
}
This way you can pass around pointer to call_spyer.
Related
I have a class, Component, which has to interact with C code.
//// Component.h file ////
class Component{
public:
uint8_t getdevice1Value();
void setdevice1Value(uint8_t value);
uint8_t getdevice2Value();
void setdevice2Value(uint8_t uint8_t);
private:
uint8_t device1Value;
uint8_t device2Value;
}
The object of the class would be created when its relevant thread is created in some Application.cpp file:
///////Some function where the Component is used//////
createThread(){
Component myComponent; // Scope within the thread
// Some actions
}
Now comes my C code, which happens to be event driven. Within these functions, I would like to link my Class methods:
//// device1_event.c file ////
void command_get_device_value()
{
// code
// assign variable = Component::getdevice1Value() function
// code
}
void command_set_device_value()
{
// code
// call Component::setdevice1Value(variable) passing some variable
// code
}
Similar to device1_event.c file, I have another device2_event.c where I would like to map the function calls to getdevice2Value and setdevice2Value.
I looked at the questions Using a C++ class member function (cannot be static) as a C callback function or also this Pass a C++ member function to a C function, where a struct registers the context and the function pointers.
I have a constraint in my case of not being able to dynamic allocation. So, I cannot use the new operator.
Now I have a few questions regarding these:
Is the callback concept applicable in my case?
If the first question is a yes, then:
How do I go about implementing it. I am a bit confused about this. I mean the call-functions need to be placed within the C-functions and also I need to register them once the Component instance is created. How can I exactly do this?
How do I bring the callback functions to my C files?
In this question a struct was employed. Where do I declare the 'struct'? I did try declaring it in the Component.h file and introduced it as an extern within the device1_event.c file. But I get an incomplete type error.
The classical C way of passing callbacks is to pass two values: a pointer to the callback itself, and an opaque pointer which will be passed to the callback as an additional argument (take a look at qsort_r for example). When interfacing with C++, that opaque value may be used as instance pointer; you will only need to write a thin wrapper:
class B {
void my_callback(int arg);
static void my_callback_wrapper(int arg, void *u) {
((B*)u)->my_callback(arg);
}
};
// or even:
extern "C" void my_callback_wrapper(int arg, void *u) {
((B*)u)->my_callback(arg);
}
and pass a pointer to the wrapper, along with a pointer to the object, to the C part. Be careful to use the exact same class type on both sides and not base/derived classes, for example.
Note that while it may be possible to get a pointer to the (non-static) method itself, on some compilers (tested on MSVC a long time ago) they have a special calling convention so that the pointer will not be compatible with any normal function pointer.
I encountered an issue while trying to do something in the process of learning C++ and I am not sure how to handle the situation:
class Command
{
public:
const char * Name;
uint32 Permission;
bool (*Handler)(EmpH*, const char* args); // I do not want to change this by adding more arguments
};
class MyClass : public CommandScript
{
public:
MyClass() : CommandScript("listscript") { }
bool isActive = false;
Command* GetCommands() const
{
static Command commandtable[] =
{
{ "showlist", 3, &DoShowlistCommand } // Maybe handle that differently to fix the problem I've mentioned below?
};
return commandtable;
}
static bool DoShowlistCommand(EmpH * handler, const char * args)
{
// I need to use isActive here for IF statements but I cannot because
// DoShowlistCommand is static and isActive is not static.
// I cannot pass it as a parameter either because I do not want to
// change the structure of class Command at all
// Is there a way to do it?
}
};
Any help would be greatly appreciated! :)
// Is there a way to do it?
No.
Either pass it as parameter, make it static, or make DoShowlistCommand non-static.
There are two potential answers here:
1. about use of non static items in a static functions:
As said in our previous question/answer, this is not possible, unless you'd have in the static function a specific MyClass object (and use object.isActive). Unfortunately, you can't do this here :
your code comments clearly show that you can't add a MyClass parameter to the function call;
the existing parameters don't suggest that you have already a pointer to parent class object;
it would not be adivsable to use global objects in such a context.
2. about what your're trying to do:
It seems that you want to have the function static, because you want to provide it in a table that maps script-commands to function pointers.
Alternative A
If all the function pointers used in commandtable are members of MyClass, you could think of using a pointer to a member function instead of a pointer to a function. The outside object/function that sets isActive on an object, could then refer the pointer to the member function, on the MyClass object it knows.
Alternative B
Revise the design of your code to implement your script engine by using the command design pattern: it's ideally suited for this kind of problems. It will require some refactoring of your code, but it will be so much more maintenable and extensible afterwards !
I don't think there is any way to do it. Here is why:
A static member function is not attached to any particular object, which means it cannot access other members that are not static, since they are attached to an object.
It doesn't look like you need to make it a static member. If you are sure you do - then pass it as a parameter. For example, make a
bool isActive();
function, and pass an argument from it to that function somewhere when you call this 'problematic' one.
You also could change your member variable to static, but it looks like you need it for EACH object, not one-for-all
I am trying to do something like this:
Create an object and bind its member functions to functions from a DLL. For example,
class A {
private:
int a;
public:
void func_a();
};
When loading from a DLL I want to create an A object, and set func_a to a function that is loaded from the DLL
A aObj;
(aObj.*func_a)() = getAdr(&s, h, "fmiGetTypesPlatform");
I do not know the syntax for it, but I mean I want to set the result of
getAdr(&s, h, "fmiGetTypesPlatform");
to an object's member function
Thanks in advance.
What you're looking for is a function pointer:
class A {
private:
int a;
public:
void (*func_a)();
};
Then, you can set this like any other pointer.
A aObj;
aObj.func_a = getAdr(&s, h, "fmiGetTypesPlatform");
Note that the referenced function, fmiGetTypesPlatform(), is a regular function. It is not a class method (i.e., no this, et al.), and it gets invoked via its function pointer.
(*aObj.func_a)();
If you know at compile time which DLL functions you want to use, you can make the class members one-line wrappers and encapsulate any data you need inside the object.
If you want to be able to assign arbitrary functions to class members, function pointers will work, with a little extra setup. Example code: http://goffconcepts.com/techarticles/calldll.html
Note that you can call a function pointer stored as a class member by name as if it were a function, with the usual object.func() syntax. In fact, this is how virtual member functions are implemented, under the hood.
If, however, the calls are not static, you still might want to put a wrapper around them so you can make the data they use private to your class.
Sorry to ask such a question as I'm sure it's been answered before, but I'm struggling to find an answer and it's not for the want of looking... anyway..
class foo
{
void read(void (*func)(obj&))
{
// many things happen to obj...
(*func)(obj); // Calls the function pointer to the handler.
}
};
class bar : public foo
{
void handler(obj&)
{
//
}
};
void main()
{
foo f;
typedef void (foo::*funcptr)(obj&);
funcptr ptr = &foo::handler;
f.read(ptr); ????
}
So basically, all I'm trying to do is pass the non-static member method called handler as a function pointer to the read method, so that when the callback is executed, the handler is called.
I've tried all sorts of ways to make this work and don't want to make static methods (for reasons I won't go into). I think I'm pretty close, but have sort of fallen over right at the end! Any help would be appreciated.
You cannot do that: unlike static functions that can be called on their own, the call of a member function requires knowledge of two things - the function being called, and the object on which to call it. That is why it is not possible to pass a member function to an API expecting a "plain" function pointer.
If you do not have access to the source of the foo class, you can create a static function that calls a member function on an object stored at a well-known location (i.e. in a static variable). If you do, consider changing the API to take a function object, similar to what functions from the standard C++ library do.
Finally, there is a common approach used in C libraries that take function pointers - passing an additional void* pointer, which will be passed back in a call to your function pointer; pthreads library does that. If this is the case, you can create a struct that wraps the invocation target object, and pass a pointer to this struct to be passed back to your static function.
AFAIK I don't think there is any other way. You will have to make the method static.
I would need a member function to be passed into a third party external method:
box_self_intersection_d(mycallback);
The box_self_intersection_d is a third party external static method, and I cannot modify it. mycallback is a method I want to pass it into the box_self_intersection_d, it is a class function and is accessing some members in this class ( have full control for this class and the mycallback)
Is there anyway I can use class member functions as callbacks without declaring them as static functions?
Edit: the signature of mycallback is (const box &boxA, const box &boxB), where box is a special class from the third party provider.
And the signature for box_self_intersection_d is
void box_self_intersection_d(RandomAccessIterator begin,RandomAccessIterator end,Callback callback)
If the function box_self_intersection_d takes a functional as parameters, and mycallback is a method of a class MyClass, you can use boost::bind:
box_self_intersection_d( boost::bind( &MyClass::mycallback, myClassInstance ) );
where myClassInstance is the instance of the class MyClass.
If the callback accepts a void* for user-defined data, you can use a static wrapper function that casts the void* argument to the class type and calls your member function.
Example:
static void Foo::callback_method(void* data) {
static_cast<Foo*>(data)->mycallback();
}
void Foo::register_my_callback() {
box_self_intersection_d(&Foo::callback_method, this);
}
Most sane callback libraries allow you to pass this void* argument to the functions as a way to have user-defined data in it. If not, you'll need to resort to the dirty method:
static Foo* Foo::callback_object;
static void Foo::callback_method() {
callback_object->mycallback();
}
void Foo::register_my_callback() {
callback_object = this;
box_self_intersection_d(&Foo::callback_method);
}
In general, if you need to pass a function, there is just no other way: Either you have a data side-channel like the void*, which your library provider seems to have omitted (and is clearly a bug in the library), or you need to transport the this pointer via a global variable.
There are a couple of possible workarounds. You can have a look here: http://www.newty.de/fpt/callback.html#member
In short, you can either:
declare a static "wrapper method" and pass the instance of the class to it,
or else store a pointer to the object as a global variable.
Hope that helps,
You haven't provided the signature box_self_intersection_d()
in general, if the signature is
void box_self_intersection_d( void *cb );
or even
void box_self_intersection_d( void (*cb)(const box&, const box&) );
then you cannot pass it a pointer to a member function.
The reason is that sizeof(a_member_function) is different than
sizeof(a_function_pointer). If this is the case, I think you are forced to use thiton's solution, and create a static function.
Since it's CGAL, the callback is actually a template parameter.
Its only constraints are "Callback must be of the BinaryFunction concept".
That is, it can be anything that is "callable" with the proper parameters.
This includes any object with a void operator() (const box&, const box&) member function.
Implementing that function in your class and passing *this for the callback would probably be the simplest solution.
There is a horrible solution that I can conceive of that means copying/pushing 'this' and function code to the calling stack, (or some other caller-allocated segment that can be made writeable and executable), and passing the address of the function to the library. The called-back function could then find its own code address, extract 'this' using an offset/pointer arith. and call a member function. Should work for multiple threads.
I hereby claim this years 'Gruesome Hack' award for a solution that makes developers feel physically ill but might still actually work if a project manager is pointing a shotgun at your head.
Rgds,
Martin