I recently started working on an iOS game and decided to write a distinct part of the project in C++. This approach seems to work fine as long as the Objective C classes simply access some members or call functions on the C++ objects. However i can't seem to find an elegant way to make my Objective C classes respond to 'events' in the C++ classes. Any event handling system that uses callbacks seems out of the question (since Objective C methods and C++ functions and probably not interchangeable). All i can think of is using the delegate pattern and writing wrapper classes around my C++ delegate classes so i can use them in Objective C code. So my question is: Is there a better way of doing this?
NB:
I would like to prevent using Objective C directly in my C++ files, since these classes are supposed to be platform independent.
You may want to consider the mechanism that CoreVideo uses.
In their model, they have a mechanism which involves registering a C callback function( http://tinyurl.com/axtxajf ), and one of the parameters to this function is a void*, which can be typecast to the Objective-C class you need access to.
Here is an example of a C function you may implement in your C++ modules to register the callback function. The parameter are the callback function and the pointer to the class instance:
SetEventCallback(EventCallbackFunction, self);
When the event needs to be handled, the callback function is called, and you can typecast the void* to call Obj-C class and invoke the method:
void EventCallbackFunction(void* objCPtr)
{
[(MyObjCClass*)objCPtr someMethod];
}
You could use C++0x lambda functions, they are interchangeable (assignable to each other) with Objective-C blocks.
Related
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 am writing code in c++. I need to support few basic data types and something like BigInt. This types will be exposed to outside world(through header file), which might also include c program.
Should I implement BigInt like data type as struct or class?
The confusion is because
1. If I implement it as class, as OO advantages, I can do all processing in class. But I may have to implement some work around for c programs
2. If I implement it as struct I need not do anything special for c programs, but I loose modularity and ease of implementation.
basically C couldn't access C++ objects, either struct/class (they're the same in C++, only differs in default visibility specifier). You have to create procedural wrapper for the C++ object (i.e. creation, method call, destruction, etc).
For creation, create a function that returns opaque pointer (in C++, this would be the object pointer). For method call, add the returned pointer (from creation function above) as one of the (typically first) parameter. For destruction it's the same as method call, but typically receives no other parameter other than the pointer above.
If you plan on using it in C, I suggest you write it in C. C++ gets along with C a million times better than C gets along with C++. Another option would be to write it in C and then provide a thin C++ wrapper that gives it an OO interface.
What is mean by delegates in c++, does sort function in c/c++ which takes a compare function/functor as last parameter is a form of delegate?
"delegate" is not really a part of the C++ terminology. In C# it's something like a glorified function pointer which can store the address of an object as well to invoke member functions. You can certainly write something like this in C++ as a small library feature. Or even more generic: Combine boost::bind<> with boost::function<>.
In C++ we use the term "function object". A function object is anything (including function pointers) that is "callable" via the function call operator().
std::sort takes a "predicate" which is a special function object that doesn't modify its arguments and returns a boolean value.
Callback functions in C++ can be (loosely) referred as a form of delegates ( though delegate term is not used for this). The callback functions use Pointers to Functions to pass them as parameters to other functions.
But delegates in C# is more advanced compared to callback functions in C++.
To delegate work means to share the work load with others. In real life, if you were to delegate your task, ie if you are a manager, you would be sharing your work expecting others to complete a task without you having to know how.
The concept is the same in C++ and any other languages having the capability of delegates. In C you could see this as a delegate:
int calculate(int (*func)(int c), int a, int b)
Because you are expected to send a pointer, to another function which will compute some work for you. I recently wrote a blog post on function pointers in Python and C, check it out, you might find it helpfull. This might not be the "traditional" way to delegate work in C or C++, but then again, the termonoligy says i am a bit right.
Delegation is mostly used as a way to pass functions to functionality embedded in a class (pimpl, aggregation, private inheritance). They are mainly (inlined) functions of one line, calling functions of member-classes. As far as I know, it has nothing to do with C#'s delegates.
In this sense, a function-pointer as used in qsort is not a delegate, but a callback in which framework modules can be extended by user-software as in the Hollywood principle.
Delegate: An object that acts like a multi-function pointer with a subscription system. It really simplifies the use of static or 'object' member function pointers for callback notifications and event handling.
This link explains Delegates in a lucid manner or you may also refer to the MSDN link.
Application is written in delphi 2010 and the underlying dll is a C++ dll.
In ideal case, when your application is in C++; The dll makes a callback to an application when an event occurs. The callback is implemented through an interface. Application developers implements the abstract c++ class and pass the object to the dll. The dll will then make a callback to a member function of your implemented class. A classic callback pattern it is.
But how do I pass a delphi object to the dll for it to make a callback.
I wouldn't really call that ideal. It is selfish and short-sighted to make a DLL that requires its consumers to use the same compiler as the DLL used. (Class layout is implementation-defined, and since both modules need to have the same notion of what a class is, they need to use the same compiler.)
Now, that doesn't mean other consumers of the DLL can't fake it. It just won't be as easy for them as the DLL's designer intended.
When you say the callback is implemented through an interface, do you mean a COM-style interface, where the C++ class has nothing but pure virtual methods, including AddRef, Release, and QueryInterface, and they all use the stdcall calling convention? If that's the case, then you can simply write a Delphi class that implements the same interface. There are many examples of that in the Delphi source code and other literature.
If you mean you have a non-COM interface, where the C++ class has only pure virtual methods, but not the three COM functions, then you can write a Delphi class with the same layout. Duplicate the method order, and make sure all the methods are virtual. The Delphi VMT has the same layout as most C++ vtables on Windows implementations, at least as far as the function-pointer order is concerned. (The Delphi VMT has a lot of non-method data as well, but that doesn't interfere with the method addresses.) Just be sure you maintain clear ownership boundaries. The DLL must never attempt to destroy the object; it won't have a C++-callable destructor that the delete operator could invoke.
If you mean that you have an arbitrary C++ class that could include data members, constructors, or non-pure methods, then your task is considerably more difficult. Follow up if this is the case; otherwise, I'd rather not address it right now.
Overall, I'll echo Mason's advice that the DLL should use plain C-style callback functions. A good rule of thumb is that if you stick to techniques you see in the Windows API, you'll be OK. If you're not in control of how to interact with the DLL, then so be it. But if you can make the DLL's external interface more C-like, that would be best. And that doesn't mean you need to abandon the C++-style interface; you could provide two interfaces, where the C-style interface serves as a wrapper for your already-working C++style interface.
You can't pass a Delphi object to C++, at least not without a very good understanding of how the object model works at the binary level. If you need callbacks, do them using C types only and plain functions and procedures (no methods) and you should be fine.
I'd like to pass to a function expecting a C++ object of a pure virtual class a Lua object of a class that derives from the pure virtual C++ class. How can I do this?
I'm new to lua and luabind so bear with me.
In C++:
struct A {
virtual void foo() = 0;
};
void do_something(A* a) {
a->foo();
}
In Lua:
class 'MyA' (A)
....
function MyA:foo()
print('hi')
end
In C++ again:
... // somehow create an instance of MyA class and named myA
// How?
// Maybe the result of a call to "MyA()"?
do_something(myA);
You would have to create a C++ class which implements your pure virtual function, then calls the Lua code. The implementation would be too complicated to just throw in here.
Basic pseudo code:
// C++
struct LuaA : public A
{
LuaA(const std::string &luacode)
: myLuaHandler(luacode)
{
}
virtual void foo()
{
myLuaHandler.call("MyA:foo()");
}
}
That example is very high level, but it's meant to show that what you want to do is non-trivial. It's the new "LuaA" that you would want to actually expose to your Lua code.
In general I prefer to use SWIG when wrapping my C++ for exposure to Lua and other scripted languages. SWIG does support this overloading of virtual methods that you are interested in (called "directors" in SWIG parlance), however, it should be noted that Lua/SWIG does not support directors. Java, C#, Ruby, Perl and Python do all have directors support in SWIG. I'm uncertain as to exactly why it is not supported in Lua.
It is possible, that since Lua does not support inheritance, the exact semantics of what you would like to accomplish are simply not possible in the way you propose.
Perhaps someone else has a better answer to the Lua side of things?
See section 10.1 in the LuaBind documentation. You basically provide a simple C++ wrapper to the LuaBind class that acts as a pass through to the underlying Lua implementation. Notice the following from this doc:
virtual void f(int a)
{
call<void>("f", a);
}
call("f", a) will invoke the Lua 'f' function, passing in the argument a.
Sorry, I would not answer the question you've asked directly, but will offer a bit of advice from personal experience instead:
If you're new to Lua, you should seriously consider writing your first bindings in raw Lua API and without such object-oriented layout. At least you will understand what is really going on.
Lua API is quite comfortable to use by itself. It does not create any extra overhead and you're in full control on what is happening. Luabind library development is a bit stale at the moment (but it looks like it comes back to life though).
You should consider if you really need to imitate deriving from C++ classes in Lua-side and, especially, on C++-side. Such thing is not-so-natural for Lua and requires noticeable overhead to be implemented. Furthermore, in C++ you're hiding the fact that you're making a non-native call to another language. Unless well documented, this is a potential source for performance issues.
When I've started working with Lua a few years ago, I've used to write bindings in the same way as you do, with Luabind, and imitating deriving from C++ objects. Now I'm using pure Lua API and simplistic procedural (as opposed to object-oriented) cross-language interface. I'm a lot happier with the result.
I will subclass the pure virtual class in C++ and then likely start with luabind (as per Aaron and lefticus' solutions). If this overhead is too great, I will just use the straight Lua C stack-twiddling API (as per Alexander).
Thus, there's no one answer here. I will post a comments with results later.
Thanks everyone!