Objective C++ call Objective C - c++

I have a growl action I need to call from Objective C++
- (NSDictionary *) registrationDictionaryForGrowl {
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSArray arrayWithObject:#"Alert"], GROWL_NOTIFICATIONS_ALL,
[NSArray arrayWithObject:#"Alert"], GROWL_NOTIFICATIONS_DEFAULT
, nil];
}
is the action in Objective C, but I need to put it in a .mm file (Objective C++) and I'm having a hard time trying to convert it properly because I need to put it inside a (C++) function inside a (C++) class.
Any idea how I could transfer this over to Objective C++?

From what I gather you want to provide a C++ object to Growl, which expects and Objective-C object. You can't do this.
Objective-C is a set of language extensions welded onto C. Objective-C++ is the result of welding exactly the same extensions onto C++. So in Objective-C++ you have both Objective-C style objects and C++ objects, and they are completely different things. One cannot be used when the other is expected. They have different ABIs, different schemes for resolving a method call/message send, different lifetime management, etc.
The purpose of Objective-C++ is not to make Objective-C objects and C++ objects compatible, but simply to make Objective-C code usable from C++ and C++ code usable from Objective-C++.
So what you could do is create your C++ class that you want to use as a delegate, and then create an Objective-C++ class that wraps your C++ class and has methods that simply forward to an instance of your C++ class.
class Foo {
int bar(int i) { return i+1; }
};
#interface ObjCFoo : NSObject
{
Foo foo;
}
- (int) bar:(int) i;
#end
#implementation ObjFoo
- (int) bar:(int) i;
{
return foo.bar(i);
}
#end

In Objective-C++ there are C++ classes and Objective-C classes. There are no Objective-C++ classes. The GrowlApplicationBridgeDelegate which implements registrationDictionaryForGrowl has to be an Objective-C object. You can define it exactly same in an .mm file as you would in an .m file. The only difference is that in your .mm file the Objective-C classes you define can call and use C++ classes and syntax.

I do not know what do you call Objective-C++, but the code above, provided it is in an Objective-C #implementation section, will compile fine with or without Objective-C++ enabled (.m or .mm extension).
By the way, if you are using Xcode 4.4 or above, the following will do as well:
- (NSDictionary*) registrationDictionaryForGrowl {
return #{
GROWL_NOTIFICATIONS_ALL : #[ #"Alert" ],
GROWL_NOTIFICATIONS_DEFAULT : #[ #"Alert" ] };
}

Related

Writing a wrapper for a C++ Factory class for use in Objective-C

I have a factory class in C++ that I need to make use of in an Objective-C project, so I am trying to write a wrapper for it.
Below is the superclass definition of the Widget class.
class Widget
{
public:
Widget();
virtual ~Widget();
virtual Thingamajig getThingamajig() = 0;
};
The factory will return a subclass of Widget, and the Objective-C program will use the Thingamajig provided by Widget (I omitted details on Thingamajig-just presume it is a very simple data container class).
Here's the factory class:
class WidgetFactory
{
public:
/*...a series of integer constants defining the different types of widgets to be returned by
createWidget function below.*/
WidgetFactory();
~WidgetFactory();
Widget* createWidget( int type );
};
Because I am writing a wrapper, the createWidget method in the factory class is non-static (createWidget was originally static).
Now, here is what I have for the Objective-C wrapper thus far. It is the header for an Objective-C++ (mm file):
#interface WidgetFactoryWrapper: NSObject
#end
#interface WidgetFactoryWrapper()
-(Widget*) createWidget: (int)type;
#end
Here are my questions:
1) I got the idea of writing the wrapper like this from another SO article here (Calling C++ from Objective-C). However, I do not think the last step of writing something like CplusplusMMClass, another Objective-C++ class that uses the Objective-C++ wrapper, is necessary here-I should just call the Objective-C++ wrapper here directly. Is my thinking incorrect?
2) While I accept that I will have to write a wrapper around Widget, will I have to do so for all its subclasses?
3) If you were in my proverbial shoes, how would you go about doing this?
I'm tempted to just translate everything into Objective-C, but I want to be able to reuse what's already been written in C++.

Using C++ class in Objective-C - Why use PImpl idiom?

Suppose I have a simple C++ class:
// MyCPPClass.hpp
class MyCPPClass {
std::uint8_t m_num1 = 0;
std::uint8_t m_num2 = 0;
std::string GetText() const;
}
and I want to use this in an Objective-C class:
// MyObjCClass.h
#interface MyObjCClass {
#public
MyCPPClass _cppObj;
}
What do I really gain from using PImpl idiom over just embedding it directly into the Obj-C class (as above), aside from having to write more code for the PImpl part ?
The downside is this C++ type MyCPPClass is now in the header file MyObjCClass.h, which other Objective-C classes that use MyObjCClass will have to import. Importing a header is like putting it into the code, so these other Objective-C classes now have C++ in their code, and so will now have to be changed to Objective-C++ files or they won't compile. This is often not desirable, as these other files shouldn't need C++. Although this problem can be solved by declaring your instance variable not in the main class declaration in the header, but in the "extension" (declared like a category but with no name in the parentheses) or in the #implementation, which are in the implementation file, so other classes don't have to import it.
Another problem with C++ classes as instance variables of Objective-C classes is that your C++ object can only be constructed using the default constructor (i.e. no constructor arguments), as there is no way to provide an initializer for an instance variable of an Objective-C class. So if you want to construct it with constructor arguments, you must use pimpl.

Calling an Objective-C Method from a purely C++ class

I have a pure C++ class that needs to retrieve an int value from some Objective-C instance method.
I understand that C++ cannot call Objective-C methods directly.
I have an Objective-C++ class that allows me to work with Objective-C and also to pass data to my pure C++ class.
However, I have not figured out a way to allow the pure C++ class to request the int value be computed and retrieved. In other words, the pure C++ needs to be able to retrieve that value whenever it needs to (via a function pointer, or whatever).
Anyone know how this is accomplished?
C++ can definitely call Objective-C code. Store the code that communicates in a .mm file instead of .cpp, and Xcode will do the rest for you.
.mm files store Objective-C++ code, which is why it works.
[Edit]
You probably have some business logic in C++, and want to combine that with your UI in Objective-C, right? Your business logic is probably shared across multiple platforms, which is why you can't just compile all your code as Objective-C++.
That's why you can basically "wrap" your Objective-C code in an Objective-C++ wrapper.
// myUI.h (C++ header)
class myUI {
void doSomething1();
int doSomething2();
}
// main.cpp (C++ code)
int main() {
myUI ui;
printf("%d\n", ui.doSomething2());
ui.doSomething1();
return 0;
}
// myUI.mm (Objective-C++ code)
int myUI::doSomething2() {
return [[MyController sharedController] doSomething2];
}
// myUI.cpp (C++ code)
void myUI::doSomething1() {
printf("Hi!\n");
}

Calling an Objective-C class method from C++

I am having some trouble calling an objective-c class method from a C++ file. Example:
In my .h:
#interface MyClass : NSObject {
}
+ (void)myMethod:(NSString *)str;
In my .m:
+ (void) myMethod:(NSString *)str { ... }
In my .cpp:
??
How can you call myMethod since there is no class instance? Its essentially a static?
Thanks
Objects in C++ are incompatible with objects in Objective-C. You cannot simply call an Objective-C method from C++.
There are some solutions, however:
Use Objective-C++. Rename your .cpp to .mm, then you can use Objective-C syntax in your C++ code: [FlurryAnalytics myMethod: #"foo"];
Use direct calls to the Objective-C runtime system. I won't tell you how to, because I really think you shouldn't, and in fact that you don't want to.
Write a plain-C interface. That is, in some .m file, define void myFunction(const char *str) { ... } and call that from C++. You can find an example of this here.
You're going to need a .mm to call an Objective-C method, rather than a .cpp. Beyond that your comment that 'it's essentially static' is accurate in the sense that you would call it with similar logic to the way you would call static class functions in C++:
[MyClass myMethod:#"Some String"];
Though the method isn't static in the C++ sense for a bunch of reasons that don't affect this answer — it isn't resolved at compile time and it does operate within a class (the MyClass metaclass).

Automatic code generation for Objective C to C++ bridge

I am seeking an opinion from the Mac/iPhone developers about a new project. The idea is to start an open source initiative using swig (www.swig.org) for automatically generating the bridge from objective c to c++ so that one can access c++ applications from cocoa/cocoa touch.
Apple provides a very good support for mixing objective c and c++ via objective c++ but writing those bridges by hand could be tedious and bug prone. What this project intend to do is to provide a way of automatically generating objective c interfaces and wrappers over c++ so that any cocoa or cocoa touch application happens to see the object oriented objective c interface with c++ underneath.
I would greatly appreciate any opinion or suggestions over this idea.
I do not think this is necessary. With Objective-C++, you do not need a bridge at all. Given a C++ class defined
class Foo {
public:
void someMethod(void);
}
you can use that class anywhere in Objective-C++ code. For example, within a method:
- (void)myObjCMethod {
Foo myFoo;
myFoo.someMethod();
//etc.
}
You can have instance variables that point to C++ classes, so you could define an Objective-C class like
#interface Bar : NSObject {
Foo *foo;
}
#property (assign) Foo * foo;
#end
#implementation
#synthesize foo;
- (void)dalloc {
delete foo;
[super dealloc];
}
- (id)init {
if(self = [super init]) {
foo = new Foo();
}
return self;
}
- (void)aMethod {
self.foo->barMethod();
}
I don't think you can template an Objective-C method, but C++ template instantiations in Objective-C++ are fair game. Just as Objective-C is a strict superset of C, Objective-C++ is a superset of C++, adding Objective-C-style classes and message passing.
If you did want to "bridge" a C++ class, you're going to have trouble in general, since things like multiple inheritance and operator overloading aren't supported in Objective-C's object model.
It strikes me as a good enough idea that I'd be surprised if something like it doesn't already exist. On the other hand, since you can compile C++ directly, (look at what a .mm extension gives you) it might be somewhat trivial.