I am loading a function from a .SO 'plugin' file in my code. The plugin will define 3 very specific functions, the full API for each function is defined ahead of time (the point is allow different instances of the same program to modify their behavior via the use of a different plugin. Due to the amount of it's use, need for speed, and my general laziness I decided to use a static function pointer which can store the plugin functions rather then passing the function pointer around various objects.
It's possible for a plugin not to exist, in which case I want to run what is essentially a 'no-op' function in place of the function that would have been read form the plugin. For general safety I want to ensure that the static function pointers point to my no-op functions.
For whatever reason I can't seem to do this. If I try to define the no-op funciton in the .h file and assign my function pointer to it I get all kinds of errors for defining a function in a .h. If I try to declare only the prototype of the method in the .h and assign the function pointer to the prototype I get an undeclared funciton exception, even if the function is defined in a .cpp file.
I know I can easily assign the funciton pointer to a no-op in my main() function. But is there a way to do this so that the .H file gaurentees that the pointer defaults to my no-op function even if I (or someone later) don't properly assign it in my main() method?
Header (say, PluginInterface.h):
extern void (*my_plugin_function_ptr)(...);
Source (say, PluginInterface.cpp):
#include "PluginInterface.h"
static void default_plugin_function(...) {/* does nothing */};
void (*my_plugin_function_ptr)(...)=&default_plugin_function;
Related
So here's the situation: I'm using C++, SDL and GLConsole in conjunction. I have a class, SDLGame, which has the Init(), Loop(), Render() etc - essentially, it holds the logic for my game class.
GLConsole is a nice library so far - it lets me define CVars and such, even inside my SDL class. However, when defining commands, I have to specify a ConsoleFunc, which is typedef'd as
typedef bool (*ConsoleFunc)( std::vector<std::string> *args);
Simple enough. However, like I said, my functions are all in my class, and I know I can't pass pointer-to-class-functions as pointer-to-function arguments. I can't define static functions or make functions outside my class because some of these ConsoleFuncs must access class data members to be useful. I'd like to keep it OOP, since - well, OOP is nice.
Well, I actually have this problem "solved" - but it's extremely ugly. I just have an instance of SDLGame declared as an extern variable, and use that in my ConsoleFuncs/main class.
So, the question is: Is there a way to do this that isn't stupid and dumb like the way I am doing it? (Alternatively: is there a console library like GLConsole that supports SDL and can do what I'm describing?)
If the only interface you have is that function pointer, then you're screwed.
A member function needs a this pointer to be called, and if you have no way of passing that, you're out of luck (I guess the std::vector<std::string>* args pointer is what you get passed from the library).
In other words, even though that library uses C++ containers, it's not a good C++ library, because it relies on free functions for callbacks. A good C++ library would use boost::function or something similar, or would at the very least let you pass a void* user_data pointer that gets passed through to your callback. If you had that, you could pass the this pointer of your class, cast it back inside the callback, and call the appropriate member function.
I am using SDL2_mixer library, but I believe that the question should hold for the general case also.
Currently, a function that I would like to use, Mix_HookMusicFinished(void (*music_finished)(void)) has a set callback to the global scope for a C style function. However, I would like to have that callback be set to a member function within my own class void CMusic::musicFinished() without having the need for a function in global scope.
Is there anyway to do this? Something like Mix_HookMusicFinished(musicFinished) would be great, but that directly has an error of argument of type "void (CMusic::*)()" is incompatible with parameter of type "void (*)()"
You need to make a "wrapper" function. However, the problem here is that you also need to be able to find the CMusic object that you want to "finish" - this is really what the crux of
argument of type ... is incompatible with ...
is all about. Since there is no way to pass a parameter to the musicFinished object, you will need some other way of "finding" the CMusic object.
If we assume there is a way to do that, then something like this would work:
class CMusic
{
...
public:
...
static void musicFinishedWrapper();
void musicFinished();
...
};
void CMusic::musicFinishedWrapper()
{
CMusic* music = getTheMusicSomehow(); // No idea how you do this - depends on your code.
music->musicFinished();
}
The reason you have to have a CMusic object is that your musicFinished expects a (hidden) this pointer argument - which is the value in music in my little function.
You could move musicFinished to your CMusic class and declare it as a static class method. static class methods aren't called on an object; they therefore don't have an implicit argument to specify the value of the this pointer, and they therefore can have the same signature as freestanding functions. You additionally can make it private to prevent anything but CMusic from using it.
However, since your musicFinished method currently works as a freestanding function and therefore probably doesn't need access to CMusic's protected or private members, and since your efforts to limit its scope presumably means that you don't want other things to call it, I personally would leave your musicFinished function as freestanding but declare it as static (or move it to an anonymous namespace, if you prefer) within the CMusic source (.cpp or .cc) file. Doing so would restrict its scope to the source file (the "compilation unit"). An advantage over a private, static class method is that it does not need to be exposed at all in a header file, so it is in some sense more private.
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.
Virtual table is arrary of function pointers.
How can i implement it as every function has different signature ?
You don't implement it.
The compiler generates it (or something with equivalent functionality), and it's not constrained by the type system so it can simply store the function addresses and generate whatever code is needed to call them correctly.
You can implement something vaguely similar using a struct containing different types of function pointer, rather than an array. That's quite a common way of implementing dynamic polymorphism in C; for example, the Linux kernel provides polymorphic behaviour for file-like objects by defining an interface along the lines of:
struct fileops {
int (*fo_read) (struct file *fp, ...);
int (*fo_write) (struct file *fp, ...);
// and so on
};
If functions in a virtual table have different signatures, you'll have to implement it as a structure type containing members with heterogeneous types.
Alternately, if you have other information telling you what the signatures are, you can cast a function pointer to another function pointer type, as long as you cast it back to the correct type before calling it.
If you know every function at compile time, then you could use a struct of differently typed function pointers (however, if you know every function at compile time, why wouldn't you just use a class with virtual methods?).
If you want to do this at runtime, then an array of void* would probably suffice. You'd need to cast the pointers in when you store them and out (to the correct type) again before you call them. Of course, you'll need to keep track of the function types (including calling convention) somewhere else.
Without knowing what you're planning to do with this it's very difficult to give a more useful answer.
There are valid reasons for implementing vtables in code. They're an implementation detail though, so you'll need to be targeting a known ABI rather than just 'C++'. The only time I've done this was an experiment to dynamically create new COM classes at runtime (the ABI expected of a COM object is a pointer to a vtable that contains functions following the __stdcall calling convention where the first 3 functions implement the IUnknown interface).
I have a static method in a cpp file (not in class) .
I want to use it globally without redeclaring it as extern .
In that case is it possible to use a global function pointer to this static method and
use this function pointer globally ??
It is possible to do what you want, but why would you avoid using extern when it does exactly what you are trying to emulate through a much more convoluted (and unreadable) mechanism?
The static declaration in C tells the compiler not to to add the function the symbol table. This means that the inker has no way to link that function in if needed by other modules. The function will still exists (but is invisible to the linker) so if one records the address of the function in a pointer one will be able to call the function with no problem.
So short answer is yes, it is ok.
Yes, making a public pointer while hiding the implementation is generally what you might expect in a factory style pattern.
It might be interesting to know why you say "I want to use it globally without redeclaring it as extern ."
Why is changing the declaration from static (making it available in that module only) to extern (making it available outside the module and publishing it) an action you want to avoid?
If it is static in a cpp file in the global namespace, then the function can only be used directly from within that cpp file. It is a kind of private helper function.
What you can do is to make a typedef on the function's prototype and introduce a public function that returns a pointer to the function or a table of pointers to different functions, which is often done in order to implement plug-ins and have some callbacks or api methods registered. + point is that you do not have a strong binding to the function.
the static specifier implies internal linkage.
You want static with external linkage, which does not require an explicit storage specifier. If your function is at namespace scope, simply remove the 'static' specifier. The default behavior at namespace scope is static with external linkage.