Calling an Objective C function from a C function passing an array of floats - objective-c

I´m trying to pass a reference of array of floats.
The problem is the call, because I´am developing for c but I want to make a call to an Objective C Function, Could anyone help me? How can I make the call?
There you have the code:
bool VideoCamera_Camera(float *buffer) {
[VideoCameraBinded VideoCamera_CameraUpdateBinded: buffer];
}
Thank you

I'm going to assume that VideoCameraBinded is an instance, and not a class. If I am mistaken, please let me know.
If you have a method defined on VideoCameraBinded's class, something like this:
- (void)VideoCamera_CameraUpdateBinded:(float *)buffer {
//...
}
then I don't know where your problem is coming from. Are you getting a specific error or some other issue?

If you have access to and can change the Objective-C code, add a C API there.
Otherwise, if you really can't change the Objective-C code you can use the Objective-C runtime directly, but this is discouraged:
#include <objc/runtime.h>
objc_msgSend(VideoCameraBinded, // receiver
sel_registerName("VideoCamera_CameraUpdateBinded:"), // selector
buffer); // comma separated list of arguments
You need to link to an Objective-C runtime library, usually libobjc:
$ clang mycode.c -lobjc
$ # or cc if you use GCC
If the Objective-C method expects an NSArray * instead of a float *, you can use Core Foundation with CFArrayRef. CFArrayRef and NSArray * are interchangeable, but CFArrayRef is a C type so you can use that. Same goes for CFNumberRef and NSNumber *, see Apple's documentation on this.

What is the parameter type for VideoCamera_CameraUpdateBinded:?
If its NSArray then you have to loop, create an array and send it like any other obj-c method. You'll have to store the floats in some kind of objects (e.g. NSNumber).
Otherwise, if the obj-c function is taking a float* then you should be good to go.
BTW, shouldn't you pass a bufferSize parameter too?

Related

Meaning of #property (readonly) void *data; in Objective c

I am new to iOS programming, I am preferring Swift language and I don't know Objective C. While I am wandering through some library, I got a value of type UnsafeMutableRawPointer in swift, that is actually a String value with utf8 encoding.
So I just looked into the corresponding objective c class and the variable is declared as
#property (readonly) void *data;
So why there is void pointer and why it is converted as UnsafeMutableRawPointer?
Consider me as a noob in Objective c or c.
Thanks in advance
This whole thing might be quite a lot for a beginner to understand. So let's start with ObjectiveC syntax:
Property #property (readonly) void *data; exposes interfaces which says there must be a method of type - (void *)data which means an instance method returning a void pointer. A void pointer being a pointer to anything.
ObjectiveC is then kind of a pure C a level deeper. I will not check exact transformation but since C has no methods this is all done with functions or even pointers to functions. So somewhere down there there should be a function (let's say the name of this class is MyDataClass)
void *myDataClass_data(MyDataClass *self) { return self->_data; } // Or whatever the implementation is
So nothing really interesting is going on under the hood. The whole thing just returns a position in memory without any further information of what should be there. You as a developer must know and interpret it. From C (or ObjectiveC) this is very simply. A few examples:
char *aString = (char *)myDataClass.data; // A pure C string. Expected to be null terminated
int *arrayOfIntegers = (int *)myDataClass.data; // An array of integers
int thirdItem = arrayOfIntegers[2];
MyDataClass *nextItem = (MyDataClass *)myDataClass.data; // A pointer to another instance
for(MyDataClass *iterator = myDataClass; iterator != nil; iterator = (MyDataClass *)iterator.data) {}
I hope you get the picture. The point is that C and then also ObjectiveC are very unsafe when it comes to data types. You can basically convert anything into anything however you want it and it will compile. The problem is what will happen in runtime.
When looking at Swift things get much safer and you can not just say something like let integer: Int = myDataClass as Int. You can force cast it and it will crash. Or you can do optional cast and it will return nil.
So once transitioned from C/ObjectiveC you will receive an unsafe mutable raw pointer. That means it got a position in memory witch it has no idea about what it is and how to use it. You may try to convert it to anything you want but it is unsafe as it will ignore all type checking. It is mutable probably because data it holds may be changed at any given time by any system. It is raw as it holds no additional information (like it's a string). And it's a pointer because it only points to a position in memory.
(All the snippets are symbolical to explain what goes on under the hood. Please do not take them literal)

Problems calling objective c #dynamic properties from objective c runtime

I'm writing lib for accessing objective c from python, so I'm using Cython and objective c runtime for access to objective c. Let we say user declare property on this way:
#property (assign) NSString *prop_nsstring_dyn;
And he wants to use #dynamic with this property. Okay, let we use this macro:
#define ADD_DYNAMIC_PROPERTY(PROPERTY_TYPE, PROPERTY_NAME, SETTER_NAME) \
\
#dynamic prop_nsstring_dyn; \
- ( PROPERTY_TYPE ) PROPERTY_NAME \
{ \
printf("returning\n"); \
return ( PROPERTY_TYPE ) objc_getAssociatedObject(self, #selector(PROPERTY_NAME)); \
} \
\
- (void) SETTER_NAME :( PROPERTY_TYPE ) PROPERTY_NAME \
{ \
printf("setting\n"); \
objc_setAssociatedObject(self, #selector(PROPERTY_NAME), PROPERTY_NAME, OBJC_ASSOCIATION_RETAIN); \
} \
After this we can call this in #implementation:
ADD_DYNAMIC_PROPERTY(NSString*, prop_nsstring_dyn, setProp_nsstring_dyn);
And if we call from objective c on this way:
c.prop_nsstring_dyn = #"test str";
or
c.prop_nsstring_dyn;
getters and setters are called correctly.
BUT, I need to set and get value of this dynamic property from objective c runtime, so if I use functions like objc_getIvar/objc_setIvar getters and setters aren't called at all, and I'm getting null pointer as result.
Does anyone knows something about how to call get/set funcs. of dynamic property from objective c runtime?
Thank you!
getters and setters are called correctly. BUT, I need to set and get value of this dynamic property from objective c runtime, so if I use functions like objc_getIvar/objc_setIvar getters and setters aren't called at all, and I'm getting null pointer as result.
This is your mistake. You should not be calling objc_getIvar or objc_setIvar to interact with another objects properties. Properties are not ivars. Properties are promises to implement methods. You cannot assume how those methods are implemented. You certainly cannot assume they are equivalent to a call to objc_getIvar (as you're discovering).
#NathanDay's approach, using KVC, is a decent approach, but [obj valueForKey:#"foo"] is not exactly the same thing as [obj foo]. Still, it's close.
First, to be clear, you do not really "get the value of an object's property." You don't even really "call object methods." You send messages to objects and they return results. Properties are mostly a convenient way to declare that you will respond to certain messages (selectors).
To send messages correctly, you'll have to call objc_msgSend. Note that there are several forms of it, depending on whether the return value is a floating point or a struct (which is the nice thing about using valueForKey:; it makes all return values look the same and you don't need to know which form of objc_msgSend to call). In any case you need to know how to interpret the return value, since it might be an id or it it might be scalar.
I do not believe it's possible to determine the return type for a selector at runtime in the most general case (for instance, if the class implements forwardingTargetForSelector:). You really should get this information from the header file at compile time. But in most cases, you can determine the return values at runtime using class_getProperty and property_getAttributes, or class_getInstanceMethod and method_getReturnType (you need to check both; there's no rule that developer must declare "property-like things" with #property).
While it's possible to get the actual C function pointer to the implementation of a method, you should generally not do this from outside of an object. There are many ways for ObjC objects to handle messages that do not translate into "call a method with that name". You should pass messages and let the object handle things itself.
But for reading and writing properties, Nathan's KVC approach is possibly all you need. Still, I'd really recommend you take another look at PyObjC, since they've already solved these issues. At the very least, I'd study their code very closely.
You can call the setter and getter methods indirectly by using the NSObject methods
- [NSObject setValue:(id) forKey:(NSString *)];
- (id)[NSObject valueForKey:(NSString *)];
where the key is the property name, if the property is a primative type like unsigned long, double etc. Then the setValue and value methods will deal with NSNumber equivalents.
Also you can call the property setter and getter the same way you call other methods, so you can use all of the dynamic method invocation features you can use with regular methods, thought you probable have already worked that out.

Writing struct into NSMutableArray

I have a game object which processed in two completely different places. In Contact Listener i check some conditions and if they occur i must save one or more portions of complex data. So i decided to use struct. For example:
struct SomeStruct
{
int value1;
int value2;
CGPoint value3;
b2Vec2 value4;
};
typedef SomeStruct SomeStruct;
In Game Scene i go through all game objects and if its the stack/array not empty, do some stuff and wipe it.
In Contact Listener it repeats from the beginning.
I must use this architecture because of strict order of execution (method must be called after other methods).
I suspect that i need something like vector or NSMutableArray (i think it will not work with struct), so vector may the the only way.
But don't understand how to achieve it. May you help me with some code/pseudocode or link to the book/article where i can found a solution?
Cocoa provides NSValue class for that purpose:
This creates an object that you can add to NSMutableArray:
NSValue *someObj = [NSValue valueWithBytes:&myStruct objCType:#encode(SomeStruct)];
You can use [someObj pointerValue] to access a void* representing the address of the structure that you put in NSValue.
There is a lot of solutions for this problem.
Don't use struct. An obj-c class is practically the same thing as a struct.
Use CFArray (CFArrayCreateMutable) and put it there as a pointer.
Use a C++ class with STL vector.
Use a C array (SomeStruct[]) and increase its length when you need it.
Use a classic implementation of a stack, with a linked list (every struct has a pointer to the next value).

Can I overload an operator in Objective-C?

Is it possible to override operator use in Objective-C?
For example
myClassInstance + myClassInstance
calls a custom function to add the two.
Operator overloading is not a feature of Objective-C. If two instances of your classes can be added together, provide a method and allow them to be added using that method:
Thing *result = [thingOne thingByAddingThing:thingTwo];
Or, if your class is mutable:
[thingOne addThing:thingTwo];
No, you can't do this in Objective-C.
You can do this now in Swift, a successor to objC. And since Objective-C and Swift are made to work together This could be interesting for you.
You may want to support subscripting for your object. Subscripting is not operator overloading, but it can be handy for a collection object. NSArray and NSDictionary both support subscripting. For example:
NSMutableArray *a = [NSMutableArray new];
a[0] = #"Hello";
The way to support index subscripting is to implement the following:
-(id)objectAtIndexedSubscript:(NSUInteger)idx;
-(void)setObject:(id)newObject atIndexedSubscript:(NSUInteger)idx];
I know this is an old question but I just wanted to leave this answer here for anybody in the future that might want to know if this is a possibility.
The answer is YES!
You'll have to use a variant of Objective-C called Objective-C++.
As an example, say you created a new Objective-C command-line tool project. In order to allow C++ functionality, you'll need to rename "main.m" to "main.mm". Afterwards, you can mix C++ code in with your Objective-C code in the same file. There are some limitations, but I've tested operator overloading and it seems to work perfectly fine with Objective-C objects as far as I can tell.
I've included sample source code to give you an idea of how to do it:
//main.mm
#import <Foundation/Foundation.h>
#include <iostream>
#include <string>
std::ostream &operator<<(std::ostream &os, NSString *s) {
os << [s UTF8String];
return os;
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSString *str = #"I'm an NSString!";
std::cout << str << std::endl;
}
return 0;
}
Here's my output after building and running this code:
I'm an NSString!
Program ended with exit code: 0
Hopefully this will be of help to somebody!
No, Objective-C does not support operator overloading.
First, operator overloading is evil. Second, C doesn't have operator overloading, and Objective-C is a proper superset of C, which only adds a handful of keywords and a messaging syntax.
That being said, if you're using Apple's development environment, you can use Objective-C++ instead of Objective-C, which gives you access to all of C++'s mistakes and misfeatures, including operator overloading. The simplest way to use Objective-C++ is just to change the extension on your implementation files from ".m" to ".mm"

How are objects passed and returned in Objective-C?

In Java, I can easily pass data using (ObjectA)objB. How can I do the similar things in Objective C? Also, why the Objective C can't return an Object, but only can return the id only? I do -(MyObj)returnMyObject{ }, but the Xcode warning me that I can't use the MyObj, but I can return the id..... -(id) returnMyObject {}.
The underlying model of Java and Apple's Objective C objects is really the same both have all objects on the heap and are accessed via pointers.
The difference is in Java the pointers are hidden so (ObjectA)objB is a pointer to data of type ObjectA. In Objective C the pointer is explicit and you need to say (MyObj*)returnMyObject{ }
id is a pointer to an object (so is an exception in that the pointer is implicit like Java)
As Mark has already pointed out; all Objective-C objects require the * at the end; it's always NSString *aString, never NSString aString.
This applies to casts as well; so you would have to do (MyObj *)anObject. Note, however, that the cast doesn't actually do anything, it's merely there as a hint for the compiler.