I am using a C library, which uses callback functions.
Is there any way I can access calling object of C++ class ?
Edit:
I am using c-client lib.
Which have function mm_log.
void mm_log(char* string, long err_flag)
which is getting internally called by library. I want to check on which Imap stream it is getting called.
More Info
you can download library from ftp://ftp.cac.washington.edu/imap
All (good) C library functions that want a callback have a void* user_data pointer as part of the function and the callback parameter. You just pass a pointer to your object as this to the function and it just gets passed back to you in the callback. Example:
typedef void (*callback)(void*);
void dumb_api_call(callback cb, void* user_data){
cb(user_data);
}
struct Foo{};
void my_callback(void* my_data){
Foo* my_foo = static_cast<Foo*>(my_data);
}
int main(){
Foo my_foo;
dumb_api_call(my_callback, &my_foo);
}
If mm_log is a function which you are implementing and the library is calling (which is a terrible way for a library to do callbacks, by the way), then there is no way you can get it to reference a member function in your class.
What you could do is use a global variable which you set to point to your object before invoking the library (and clear after) and then use it within mm_log to invoke the desired method. This is nasty and dangerous but can work.
If you have more than one thread then exercise extreme caution - or find a better library.
Code is important for such a question. But without seeing any of your code, I can still give you a blanket statement :)
You'd have to wrap your C++ object with global functions that access a plain-old-struct, and export those with:
extern "C"
There are a plenty of caveats, but this is the gist of it.
See this FAQ: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
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 new to Objective-C and I need to overcome the following issue.
I am trying to develop a front-end for a C library and I need to somehow get the address of an Objective-C member function and pass it to the library.
For instance: here's what I would do in C++
class MyClass
{
public:
void my function();
void some_other_function()
{ connect_signal(my_function); }
};
Here, I just pass the address of my_function() to connect_signal.
Is that possible in Objective-C? Any other ideas?
My second choice would be to simply write a C function out of the class that would call the Objective-C function.
Thanks in advance
There’s a methodForSelector: method that returns an IMP, a pointer to the implementation of a method for given selector (related question). Is that what you’re after?
And as a more general remark, using a pointer to a method implementation is usually too much magic. Is there a higher-level, more “ordinary” solution to your use case? (I can’t really imagine the details from what you wrote in the question.)
For the record, you can't connect a signal to a nonstatic C++ function. At least not in the *nix meaning of signals. Those need a this pointer for invokation.
Now, about Objective C. Depends on what do you want to do - pass a pointer to an Objective C method to a plain-C API, or implement a signal-like callback mechanism of your own. Other answers concentrate on the former; let's talk the latter.
The natural thing to do is passing around a combination of a selector and an object pointer. Selectors have datatype SEL and are retrieved using the #selector() construct. A selector is a piece of data (really an integer) that uniquely identifies a method within a class hierarchy.
Let's imagine you have a connect_signal function somewhere that wants a callback:
-(void)connect_signal:(SEL)callbackSelector forObject:(NSObject*)callbackObject;
You call it like this (from within the callback object):
[xx connect_signal:#selector(MyMethod:) forObject:self];
Within the function, you save the selector and the object pointer. When you need to invoke the callback, you would issue the following call:
[SavedCallbackObject performSelector:(SavedCallbackSelector) withObject: nil];
The second parameter is for passing parameters to the callback; if you need more than one, see NSInvoke.
My answer is assuming Cocoa. NSObject, e. g. is a Cocoa class. It's a safe bet for ObjC questions these days, considering.
Or you can use good old function pointers. They're still around.
An Objective-C method implementation (IMP) is a C function that takes at least two arguments; the target of the method call (self) and the selector to be invoked (_cmd).
Thus, passing an IMP to your C API won't work.
Your best bet is to pass a C function. Assuming your C API is sensible and has an "arbitrary user context pointer thingy", something like:
void myfunc(void *context) {
[(MyClass *)context callback];
}
i need to write a library in c++ , usable by client to do some operations in a remote server. The only thing in the specific i haven't done yet it's: The c++ library need a C interface. Let me explain better:
From client using this lib i need to do call something like:
int operation(void* addr);
if int<0 error
and so..
But the library it's a class in c++.
So my answer is.. Need I a global variable holding the instance of class in the library?
The are some better option to develop this C interface of C++ class?
Thx in advice for answer.
You can use the PIMPL idiom in the C wrapper. You provide a method YourClass_Create that internally calls the constructor (using new) and returns the pointer to your class instance; for the client code this will be just an opaque handle (it may be a typedef for void *), to be passed to every function of your C interface to specify on which instance it has to work (just like FILE * in stdio).
All these functions will have to do is to call the corresponding method on the handle (converted back to a pointer to your class) and translate exceptions to error codes.
As #jdv-Jan de Vaan pointed out in his comment, don't forget the necessary #ifdefed extern "C" {} around your C wrapper code, otherwise you may get linker errors.
I would like to make an alias in C++ to singleton calling
so instead of calling MYCLASS::GetInstance()->someFunction(); each time, I could call just someFunctionAlias(); in my code.
Use a static function.
namespace ... {
void someFunction() {
MYCLASS::GetInstance()->someFunction();
}
};
Edit: Sorry lads, I wrote static someFunction and meant void someFunction.
typedefs are used for type aliases but can't be used as call alias.
functions (such as suggested as by DeadMG) can be used as a call "alias".
PS. As this is C++ you have lots of options, function pointers, std::tr1::function<> operator overloading and the preprocessor. But in this case it certainly looks like a simple function would be the simplest and best solution.
Look up function pointers.
You can create a function pointer, and assign it to your long function. You can then call this function pointer just like a regular function, wherever your variable is defined.
Function pointers can be confusing, but are used a lot in API callbacks (i.e. you pass a function as an argument to the API, and the API will call that function when something happens (think WndProc)).
Good luck.
you can do this
#define someFunctionAlias MYCLASS::GetInstance()->someFunction()
I have a DLL which has a function which accepts a function pointer converts it to a boost::function. This is then stored and then called from inside the DLL.
I want to add a function to the DLL to handle member functions in a similar way. I know I need to use boost::bind to wrap the member function pointer and the object together. I want to do the binding on the DLL side though so the EXE does not require boost libraries to be included.
How would you write this function? One which accepts a member function pointer and an object as arguments and binds them together.
Thanks!
you're warned by #Kylotan, so you can try something like this:
__declspec(dllexport) void store_mem_fn(void(Your_class::*mem_fn)(void), Your_class& instance)
{
std::vector<boost::function<void(void)> > container;
container.push_back(boost::bind(mem_fn, instance));
}
It might be a bad idea to try passing member function pointers into DLLs because they can vary in size depending on certain circumstances. (Some details here.) Maybe if you always know that you will be building both halves of the application with the same compiler you will be ok.
As for the function, I expect it would look something like this (completely untested and uncompiled code):
typedef void(ObjectType::*OTMemberFn)();
boost::function<void (ObjectType o)> bind_mem_fn(ObjectType o, OTMemberFn mf)
{
return boost::bind(mf, o);
}
Isn't Boost open source? If so, peek into the boost code, learn how it's done, and re-implement it yourself, without the dependency.