Call objective c++ method from objective c - objective-c

I'm just learning Objective C (and objective-c++ for that matter) and I have an Objective-C++ class with the following constructor.
void InputManager::_init (int inputAreaX, int inputAreaY, int inputAreaWidth, int inputAreaHeight)
How do I invoke this from objective C?

This appears to be a pure C++ method so it would work exactly the same as in ordinary C++ (even in an Objective-C++ file). For instance you might have defined a variable on the stack:
InputManager mgr; // or, include constructor arguments if the class can't be default-constructed
mgr._init(x, y, w, h); // this assumes 4 variables exist with these names; use whatever parameter values you want
The name _init is a bit weird though; do you mean for this to be a constructor for the class? If so, InputManager::InputManager(int x, int y, int w, int h) should probably be defined instead.
If you actually want this class to be Objective-C only, the syntax and behavior are different.

You have two options:
Option 1.
Translate it into Objective-C only code. I'm not so good with C++, but this might be what it looks like in the .h:
-(id)initWithAreaX: (int) inputAreaX AreaY: (int) inputAreaY AreaWidth: (int) inputAreaWidth AreaHeight: (int) inputAreaHeight;
Since it looks like that's a constructor method, it would probably look like this in the implementation:
-(id)initWithAreaX: (int) inputAreaX AreaY: (int) inputAreaY AreaWidth: (int) inputAreaWidth AreaHeight: (int) inputAreaHeight {
self = [super init];
if(self) {
//Custom Initialization Code Here
_inputAreaX = inputAreaX;
_inputAreaY = inputAreaY;
_inputAreaWidth = inputAreaWidth;
_inputAreaHeight = inputAreaHeight;
}
return self;
}
And you might call it like this:
InputManager *object = [[InputManager alloc] initWithAreaX: 20 AreaY: 20 AreaWidth: 25 AreaHeight: 25];
Option 2.
The whole purpose of Objective-C++ is to allow the developer to integrate C++ and Objective-C code. You want to know how to call an Objective-C++ method from Objective-C, but the entire purpose of Objective-C++ is to integrate the two, so there's no point to trying to find a loophole to call an Objective-C++ method in a file that is otherwise completely Objective-C. So the second option is to just make the file that you want to call the Objective-C++ method in an Objective-C++ file with a ".mm" extension.
Hope this helps!

Related

libobjc: Calling a ObjC method from plain C?

I am currently experimenting with the V programming language and looked at a few fun things I wanted to try out. One of the things that I wondered was, if I could call Objective-C methods from plain C without compiling a single .m file.
Since Python can do it with pyobjc, I wonder if I could make it work in V?
Imagine the following, very crude code:
#implementation Foo
- (id) greet: (char*)me {
printf("Hello %s!", me);
}
#end
Now, I know that with objc_sendMsg I can send messages - but how do I create the proper instance first?
It's going to look something like this:
Class fooClass = objc_lookUpClass("Foo");
id obj = class_createInstance(fooClass, 0);
SEL initSelector = sel_registerName("init");
((id (*)(id, SEL))objc_msgSend)(obj,initSelector);

C function accessing private ivar of Objective-C class

According to this comment:
C functions inside #implementation blocks have the unique property of
being able to access private and protected ivars directly. Thus, from
my own experience, it's become a strong idiom to place C functions
that "belong" to a class inside the corresponding implementation.
My code, defining a private instance variable in the implementation only as suggested by this answer:
With the brackets:
#implementation ViewController{
MyTest *tt;
}
void testf(){
NSLog(#"hello back from c++ into obj c land");
[tt testcf: 5];
}
...
Will not build; the compiler indicates that tt in testf is undeclared. If I remove the brackets, then the C function works fine.
But... if I remove the brackets, do I understand that actually this is no longer an instance variable, but sneakily it is a global variable, disconnected from the class, despites its placement in the #implementation? It would appear that this is indeed true, since I can do this as the end:
#end
void testf2(){
NSLog(#"hello back from c++ into obj c land");
[tt testcf: 5];
}
And the compiler does not contain about tt being out of scope. So -- how to declare a private instance variable in an implementation and have it truly be an instance variable, but also have a C function be able to access it? For the purposes of this question, I am trying to get this to work based on the linked comments/answers without using the id pointer of the object itself.
You will need to pass a reference to self to the C-function:
void testf(ViewController *vc){
NSLog(#"hello back from c++ into obj c land");
[vc->tt testcf: 5];
}
and call it like this:
- (void)someMethodInViewController
{
testf(self);
}
However it's not clear why you are using C-functions at all.

concept of object from c/python to object-c

I have experience on C and Python,
I learned the Object-C today,
I want to make sure if my concept is correct ?
I don't know why should I put a statement in a bracket
[pt setX: 8];
Isn't pt setX: 8 meaningful enough ?
If brackets is only for readable, why I got errors in this picture,
I just want to know when should I use the bracket , and when isn't need.
Is pt setX: 8 similar to pt.setX(8) in Python or C-like language?
To create a object,
You have to define .h .m,
In C, you can define and implement both in a .c file , but can not in object-c ?
If you want autorelease the object memory without explicitly free the memory in manual,
Just put your code in the #autoreleasepool block, right ?
#autoreleasepool {
MyPoint* pt = [MyPoint alloc];
// call constructor
pt = [pt init];
[pt print];
[pt getArea];
[pt setX: 8];
[pt setY: 99];
[pt print];
[pt getArea];
}
MyPoint.m
//
// MyPoint.m
// hello_world
//
// Created by poc on 2014/4/27.
// Copyright (c) 2014年 poc. All rights reserved.
//
import "MyPoint.h"
#implementation MyPoint
- (void) print
{
NSLog(#"X =%i and Y= %i", _x, _y);
}
- (void) getArea
{
NSLog(#"Area is %i", _x*_y);
}
- (void) setX:(int)aX
{
_x = aX;
}
- (int) getX
{
return _x;
}
- (void) setY:(int)aY
{
_y = aY;
}
- (int) getY
{
return _y;
}
#end
Is pt setX: 8 not meaningful enough ?
No, it's not. Let's assume situation when you want use result of method invocation as object
pt area intValue // without brackets it's a mess
[[pt area] intValue]; // looks readable now
Is pt setX: 8 similar to pt.setX(8) in Python or C-like language?
Yes, it similar. But you need square brackets
In C, you can define and implement both in a .c file , but can not in object-c ?
Analog of .c file for obj-c is named .m. There you can do the same stuff as you can in .c, importing of .m is really bad practice, it leads you in majority of cases to incorrect linking and, eventually in failure of build. Also it good way to separate private and public interfaces. .h contains public interface to class, you import .h and see only public methods and class variables, while .m contains private methods and variable that you don't want to expose.
If you want autorelease the object memory without explicitly free the memory in manual,
Just put your code in the #autoreleasepool block, right ?
No, it's not. You can't count on autoreleasing of variables you puts there. Autorelease pool created for another purpose. If you want to know why - read this.
I encourage you to use ARC (automatic reference counting), it's enabled by default in latest project templates in Xcode. This way you don't need to worry about memory management, while you correctly use naming convention.
I don't know why should I put a statement in a bracket
That's just the syntax for method calls. Why are parentheses required around arguments in C and Python? Syntax. Other languages don't require parentheses or brackets for method and function calls (e.g. Smalltalk, Ruby and Perl, though parentheses allow you to be more expressive) because they use different syntax. Smalltalk, in particular, is similar to Objective-C method calls, but without the brackets (not coincidentally, since Smalltalk inspired Objective-C).
Is pt setX: 8 similar to pt.setX(8) in Python or C-like language?
Yes. In particular, [pt setX: 8] calls method setX on (or, if you prefer, sends message setX to) object pt, passing 8 as a parameter.
In C, you can define and implement both in a .c file , but can not in object-c ?
Keep in mind that anything declared solely in a compilation unit (a ".c" file) isn't accessible in other compilation units. With Objective-C, you can declare both static variables (as you might in C) and methods in a compilation unit (which have that ".m" extension), but they are effectively private.
If you want autorelease the object memory without explicitly free the memory in manual, [j]ust put your code in the #autoreleasepool block, right ?
An #autoreleasepool block isn't responsible for keeping track of object lifetime; see "Why is autorelease (#autoreleasepool) still needed with ARC?" for what it does. See also "Transitioning to ARC Release Notes" for info on Automatic Reference Counting (ARC) and "Memory management" for info on the older approach (manual reference counting), which is what ARC does under the hood.

How do I write to an NSObject from within a C function that doesn't see Obj-C variables?

I'm trying to get some code going that lets me display raw trackpad data from my macbook pro, like the app FingerMgmt. Unfortunately, no one seems to have the source for FingerMgmt. I did find some other source code that kind of works, however. I was able to NSLog the data I wanted to see like this:
int callback(int device, Finger *data, int nFingers, double timestamp, int frame) {
for (int i=0; i<nFingers; i++) {
Finger *f = &data[i];
NSLog(#"Frame %7d: Angle %6.2f, ellipse %6.3f x%6.3f; "
"position (%6.3f,%6.3f) vel (%6.3f,%6.3f) "
"ID %d, state %d [%d %d?] size %6.3f, %6.3f?\n",
f->frame,
f->angle * 90 / atan2(1,0),
f->majorAxis,
f->minorAxis,
f->normalized.pos.x,
f->normalized.pos.y,
f->normalized.vel.x,
f->normalized.vel.y,
f->identifier, f->state, f->foo3, f->foo4,
f->size, f->unk2);
//todo-get data from raw C to obj-C variable
}
return 0;
}
But whenever I try to store any of the data to an Obj-c string or variable, the C code does not see the variable as having been declared. Because of this, I cannot write to any text fields or graphical displays in Obj-C, and I cannot store the data to a variable that Obj-c can access.
Basically, I need a way to write to an Obj-C variable or object from within the callback.
On a side note, I had a very similar problem with an iPhone app a while back, and I ended up fixing it by somehow declaring the app delegate within the C code and writing to or reading from the variable like this-
me.delegate=(id <UIApplicationDelegate,UITabBarControllerDelegate>)[[UIApplication sharedApplication] delegate];//allows access to the delegate within C function
me.delegate.number0=5;//writes to this variable in the delegate
For some reason, I can not seem to adapt this to my current situation. I always get the error that "me" is undeclared.
A Objective-C method can access instance variables because it is automagically passed a hidden parameter with the public name self - any reference to an instance variable, say fred, is translated by the compiler into a field reference, say self->fred (and a similar translation for property references).
For your C function callback to access the fields of any object (or call an object's methods) you need to pass the function a reference to the object. Two simple ways:
Add an argument to the function. Many C callback protocols include a general "user defined" values which is passed around as void *, if you are calling one of these pass your object reference as this value and cast it within the C function back to the correct Objective-C type.
Pass the object via a global (or file static) variable, e.g. static NSSomeType *objectForCallback;. This method works when you're stuck with an existing C callback protocol which doesn't support a user defined value. However it is not thread or re-entrant safe as you are sharing a single static variable.
In both cases make sure the objected is retain'ed if you're not using garbage collection.
In response to comment
Case 1: You will see C functions declared which (a) take a callback function and (b) a user-defined value to pass to that function on every call. For example:
typedef T ...;
T findMatching(T *buffer, // an array of T to search
size_t count, // number of items in array
int (*matcher)(T item, void *user), // user function for match, 1st arg is item, 2nd user-supplied value
void *userValue); // user-supplied value to pass to matcher
If you are faced with C function like this you can pass a (retain'ed if needed) Objective-C object as userValue and cast it back to its Objective-C type inside matcher. For example:
int myMatcher(T item, void *user)
{
NSMutableDictionary *myDictionary = (NSMutableDictionary *)user;
...
}
- (void) someMethod
{
NSMutableDictionary *sharedWithC = ...;
...
T found = findMatching(buffer, count, myMatcher, (void *)sharedWithC);
...
}
Case 2: Objective-C is (a superset of) C. You declare a global just as you would in C. For example (little checking, not thread safe):
static NSMutableDictionary *myGlobalDictionary = nil; // "static" makes the variable only visible to code in the same file
- (void) setupTheSharedDictionary
{
myGlobalDictionary = [[[NSMutableDictionary alloc] init] retain];
}
- (void) releaseTheSharedDictionary
{
if(myGlobalDictionary != nil)
{
[myGlobalDictionary release];
myGlobalDictionary = nil;
}
}
In response to second comment
I'm guessing you are trying to use some third party (Google?) code. That code defines a callback protocol - a C function type. You cannot just redefine that C function type adding an extra argument and expect the third party code to magically cope!
So unless you intend to change the C you can use the second approach - store the reference to Objective-C object in a global. In your case this will be something like:
static MT2AppDelegate *sharedWithCAppDelegateReference;
int callback(...)
{
...
[sharedWithCAppDelegateReference->L1 setStringValue:#"Hellofff"];
...
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
sharedWithCAppDelegateReference = self; // store so C can pick it up
...
MTRegisterContactFrameCallback(dev, callback);
...
}
But remember this is not thread or re-entrant safe - you are effectively passing a function parameter via a global variable. If you need it to be thread/re-entrant safe you need to get a bit more involved.

What you can't do in C that you can do in Objective-C?

What you can't do in C (C99 standard) that you can do in Objective-C? (with code example if you please)
I'm going to be a little bit presumptuous and disagree with everyone else. While it's technically true that anything possible in one language is possible in another (where "possible" means "computable"), they differ in what you can express naturally and easily. The computer might be doing the same thing in response to the code you write in C, but you are writing radically different code to make it do those things.
As others have said, Objective-C provides a full runtime library written in C that will allow you to create Objective-C data structures and call C functions, but the code to do it will be very verbose, fairly roundabout and completely imperative. In Objective-C, the code is more declarative, more concise and far more readable.
In general, trying to write Objective-C things in C will only make your code worse than it would be using either language idiomatically. For example, here is a simple program written in Objective-C:
#interface NumberAdder : NSObject {
int storedValue;
}
- (id)initWithStoredValue:(int)value;
- (int)resultOfAddingStoredValue:(int)numberToAdd;
#end
#implementation NumberAdder
- (int)resultOfAddingStoredValue:(int)numberToAdd {
return numberToAdd + storedValue;
}
- (id)initWithStoredValue:(int)value {
if (!(self = [super init])) return nil;
storedValue = value;
return self;
}
#end
int main() {
id adder = [[NumberAdder alloc] initWithStoredValue:4];
int result = [adder resultOfAddingStoredValue:3];
printf("It is %d\n", result);
return 0;
}
And here is the same thing written in C with the Objective-C runtime (not tested, but should be roughly correct):
int returnPlusStoredValueImp(id self, SEL _cmd, int arg) {
int *storedValue = nil;
object_getInstanceVariable(self, "storedValue", &storedValue)
return arg + *storedValue;
}
id numberAdderInit(id self, SEL _cmd, int valueToStore) {
objc_super superInfo = {self, objc_lookupClass("NSObject")};
self = objc_msgSendSuper(super_info, sel_getName("init"));
if (!self) return nil;
object_setInstanceVariable(self, "storedValue", &valueToStore);
return self;
}
void createNumberAdderClass() __attribute(constructor)__ {
Class NumberAdder = objc_allocateClassPair(objc_lookupClass("NSObject"), "NumberAdder", 0);
if (!NumberAdder) return;
class_addIvar(NumberAdder, "storedValue", sizeof(int), 4, "i"); // I'm actually not sure if the fourth argument is correct, so it's probably wrong, but just take that as a sign of how much this way of coding sucks
objc_registerClassPair(NumberAdder);
SEL nameOfPlusStoredValue = sel_registerName("resultOfAddingStoredValue:");
SEL nameOfInit = sel_registerName("initWithStoredValue:");
class_addMethod(NumberAdder, nameOfPlusStoredValue, returnPlusStoredValueImp, "i#:i");
class_addMethod(NumberAdder, nameOfInit, numberAdderInit, "##:i");
}
int main() {
id adder = objc_msgSend(objc_lookupClass("NumberAdder"), sel_getName"alloc");
adder = objc_msgSend(adder, sel_getName("initWithStoredValue:"), 4);
int result = (int)objc_msgSend(adder, sel_getName("resultOfAddingStoredValue:"), 3);
printf("It is %d\n", result);
return 0;
}
Absolutely nothing. Objective-C's OO features are implemented as a small runtime library written in C.
While some commenters might point out that Objective-C has blocks and C doesn't, that's actually a GCC/LLVM extension to C that Objective-C makes use of, it's not an ObjC feature.
As Graham said -- there is absolutely nothing that can be done in Objective-C that can't be done in C. Of course, there isn't anything you can do in C, either, that can't be done in assembly. It is just a matter of typing.
(I was hoping that the the assembly mention would be enough to indicate that, no, I'm not remotely suggesting that writing OO patterns in pure C is remotely a productive thing to do...)
There are a few additional points of interest:
Objective-C started out as a preprocessor that turned Objective-C code into C code that could be compiled by a standard C compiler. That is, Objective-C was originally never directly compiled, but translated to straight C, then compiled.
Objective-C objects can be thought of as C structures where the first entry in the structure -- the isa -- is always a pointer to the metadata -- the Class -- that describes the structure/instance.
Blocks are an extension to C, now proposed as an addition to the C language in WG-14 (C standards committee). Blocks, as implemented by Apple, absolutely do not require an executable stack. It was a hard requirement in their design.
LLVM has a rewriter that can actually rewrite Objective-C to C and has, apparently, been used to enable Objective-C coding in Xbox 360 games (see http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/31996).
There isn't such a thing. Generally, you can program anything in any programming language.