Calling an Objective-C class method from C++ - 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).

Related

How to pass a callback function from C++ to Objective-C

I don't want to use NSNotification because it is so messing up internally. Is it a way to pass a callback function from C++ to Objective-C++, and let Objective-C call it?
The problem is that I don't know how to pass a function written in C++ to Objective-C++, and how could I use that callback in Objective-C++? Is it a pointer?
I know I can mix them up but my class has to be a C++ class because it inherits some C++ classes.
You're not 100% specific as to the exact use case you're trying to cover here, but I'm going to set out a scenario where this kind of situation occurs, and then show you how to solve it. I hope that will cover your problem too.
So I'm going to assume you have an Objective-C class MyClass with its interface declared in MyClass.h:
#interface MyClass : NSObject
- (void)someMethod;
- (void)otherMethodWhichShouldTakeACallback:?????;
#end
You now have a C++ class MyCPPClass, declared in MyCPPClass.hpp on which you want to pass memberFunction as the callback argument to the otherMethod on MyClass:
class MyCPPClass : public MyBase
{
void memberFunction();
};
First, we need to figure out the method signature on MyClass. The modern way for callbacks in Objective-C is with Blocks. Blocks work pretty well with Objective-C++, so let's go with that and modify MyClass.h with the following line:
- (void)otherMethodWithBlock:(void(^)(void))callbackBlock;
The calling code will need to reside in an Objective-C++ compilation unit (caller.mm):
void callOtherMemberWithCPP(MyCPPClass* cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
Note that this does not deal with object lifetimes. If you're managing lifetimes on the C++ side with std::shared_ptr, you can use that in your Objective-C++ code too, in which case we might end up with something like:
void callOtherMemberWithCPP(std::shared_ptr<MyCPPClass> cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
In this case, the C++ object will only have its reference count decremented when the Objective-C class is done with the block.
For completeness, the other way to do this would be to use C function pointer syntax. In this case, you would need to declare the Objective-C method along these lines:
- (void)otherMethodWithCallback:(void(*)(void*))callback object:(void*)opaqueCallbackArgument;
And the C++ class's method call would need to be wrapped in a free function or static member function:
void memberFunctionCallback(void* opaque_object)
{
MyCPPClass* object = static_cast<MyCPPClass*>(opaque_object);
object->memberFunction
}
…and then call the Objective-C method like this:
[objc_obj otherMethodWithCallback:memberFunctionCallback object:cpp_obj];
Making this version work nicely with automatic lifetime mechanisms such as shared_ptr is a lot more tricky though.

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.

Objective-C++: Headers and Class Methods

I've been learning Objective-C for the last few months with the goal of writing iOS games. I want to be able to make the games relatively easy to port to other platforms, so I've also been simultaneously learning C++. My plan is to write most of the game in C++ and write the drawing and game loop in Objective-C. I know (at least I've been told) this is possible, but there are a few things that I'm still confused about.
I'm still pretty new to C++, and coming originally from Java, is it a bad idea to have functions return type be void?
Is there a way to write class functions? ie. className.function(); rather than object.function();
I've never needed header files for my C++ files before. Could someone point me in the direction of an example? Preferably one that has a constructor method? I don't know what to make its return type. (It should be a pointer to the class right?)
I'm going to assume your questions are about how to write C++, as that seems to be what you're asking.
Not at all, void functions are well-accepted in nearly all languages, C++ and Objective-C included. (Though many people prefer returning a bool success/fail value)
You're probably looking for static functions. These don't require instantiation, but there are some limits on their use (see here for more info).
Any non-trivial C++ project should use header files. They serve several purposes, including keeping your code more organized and modular, decreasing compile-time in many cases, and aiding in conceptualizing your design before you think about implementation.
An important thing to note when breaking your class into .h and .cpp files is the use of the scope modifier :: when defining functions. When defining the function public void foo() in your .cpp file, after having declared it in your header, you must use public void ClassName::foo() { }. This is because you defined foo while in the class ClassName { } block in your header, but you are now in the global scope.
(As for your question about C++ constructors, if should be public ClassName::ClassName(); and you don't need to return anything).
Now obviously, many of these points differ in Objective-C. For example, the init method (comparable to the C++ constructor) does, as you said, return a pointer to the object being inited. If you want specific information on writing cross-language apps, you should update your question to be more specific, or open a new question.
No that is fine.
Yes: Assume SomeClass.h:
#pragma once
class SomeClass {
public:
static bool myStaticMethod();
};
and in SomeClass.cpp:
#include "SomeClass.h"
bool SomeClass::myStaticMethod() {
// A static method
return true;
}
See the first part of 2, above.
Some other notes:
A. Change all your Objective-C interface code to Objective-C++ by renaming all the .m files to .mm. This way you can use your C++ code freely.
B. I couldn't think of a B.

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 Objective-C methods from CPP code

I am very new to Objective-C.
I wan to call Objective-C methods from a C++ class defined in separate .cpp file.
I have used the same mechanism described in this question's answer by dreamlax (not the PIMPL one)
http://stackoverflow.com/questions/1061005/calling-objective-c-method-from-c-method
But i am stuck at point how to call function int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter); from CPP class with the parameters objectiveCObject.
Also can some one please explain how to call a C++ class functions from Objective-C Code with an Example.
You must use Objective-C++ in the file that does the call. To do so from Xcode, rename the file from Whatever.m to Whatever.mm. Then you can mix calls.