calling a c function in another class - objective-c

i am having objective c class, which i have a C function in it.
in that C function i want to call to ANOTHER c function in another class.
in the first class C function , i do this :
HelloWorldLayer *ran;
ran=[[HelloWorldLayer alloc] init];
[ran showDigital:BinaryWord];
when HelloWorldLayer is the other class, which have the C function :
void showDigital( int word[4])
and it declared also in the HelloWorldLayer.h .
in the first class, when i am trying to call the other function it says that showDigital function is not found.
is it has to do with the fact that its a C function ?
thanks.

Do you want to call a C function or an Objective-C method? You've got your terminology all muddled. I think you want to define an Objective-C method on HelloWorldLayer and call that, so here is what your header should look like:
HelloWorldLayer.h
#interface HelloWorldLayer : NSObject
- (void)sendDigital:(int[4])word;
#end
Then you can call that method by doing what you have already tried.
You can't declare a C function inside an Objective-C class. You could define it in your #interface block, but it wouldn't be part of that Objective-C class. Only Objective-C methods can be part of the class.
So for instance if you really really really wanted you could do:
HelloWorldLayer.h
#interface HelloWorldLayer : NSObject
void sendDigital(int[4] word);
#end
But when you called sendDigital you'd have to do it like this:
int word[4] = {1,2,3,4};
sendDigital(word);
And you'll notice there's no HelloWorldLayer around at all. Now do you understand the difference here? I really do think you need to define your method as an Objective-C method rather than a C function.

First of all, the C function is not in the other class, it is merely in the same file as the other class. Objective-C classes have methods not functions.
So you can call your C function from anywhere provided you have an extern declaration of it. e.g. in HelloWorldLayer.h
extern void showDigital(int* word);
If you really want the function to be associated with instances of your class, you need to make it an Objective-C method. You can have that method be a thin wrapper for the original function if you like:
-(void) showDigital: (int*) word
{
showDigital(word);
}
If you want to pretend that your C function is part of an object, you'll need to add the receiver object as a parameter. You still won't be able to access private instance variables directly though.
void showDigital(id self, int* word)
{
[self foobar];
}

Related

Need help turning a C function into an Objective C method

I have a function written in C that is rather large and currently is only running in the main() function of a C file while I have been using to test it out. Here is it's declaration
void getData(const char* encodedBuffer, int user);
If you would like to see the contents of getData Here is the pastebin for it.
As of now I'm just passing in encodedBuffer which I will have a global variable that is getting updated by the getData function.
I would like to know what the proper way is to turn a C based function like this into a Objective-C protocol method. Right now I'm setting it up like this
iDriver.h (my interface/protocol)
#import <Foundation/Foundation.h>
#protocol iDriver <NSObject>
-(void)getData;
-(void)cancel;
#end
DriverOne.h (Class that actually implements the protocol method)
#import <Foundation/Foundation.h>
#import "iDriver.h"
#interface DriverOne : NSObject <iDriver>
#end
DriverOne.m
#import "DriverOne.h"
#implementation DriverOne
enum Status getData(char* encodedBuffer, int user)
{
// Copy C code which I showed in the link earlier
// to above into this method. I will want it to return a status
// and populate a global variable with the data.
}
My thought is that I shouldn't really run into any issues doing this since Objective-C is a superset of C but just copying the C code into a method like that be problematic?
When porting a C function to an ObjC method, it's just a tweak to the signature. In your case, you'll change:
enum Status getData(char* encodedBuffer, int user)
to something like:
- (enum Status) getData: (char*) encodedBuffer user: (int) user
Objective C methods are always denoted with a - at the beginning (class methods start with a +). If you want to specify the type, you put in parens (otherwise it's assumed to be type id which is generic for "object"). And you have to keywordize your function name. One keyword for each argument.
Then just like C, you can just copy paste that line into your header file:
#protocol iDriver <NSObject>
- (enum Status) getData: (char*) encodedBuffer user: (int) user;
#end
After that just copy the guts inside the method.
It's not clear how familiar you are with the ideas behind OO and instances, but using it might look something like:
DriverOne *driverOneObject = [[DriverOne alloc] init];
char *buffer = malloc(YOUR_BUFFER_SIZE);
enumStatus status = [driverObject getData: buffer user: SomeUserThing];
Coming full circle, is there a reason you want this to be reified (turned into objects)? I'm all for lots of objects myself, but one of the features of ObjectiveC, is that it IS a superset of C. You can just use your function as is from your C prototype. You don't have to wrap it up in an ObjectiveC object, unless you see an advantage to doing so.

Pass instance method as function pointer to C Library

I am writing an Objective-C application that uses a C Library. The issue which i am currently facing is that the C Library has a structure where some field are function pointers later used as callbacks. How can i convert an Objective-C instance method to a function pointer and pass it to the library?
You will need to provide the C callback function within the Objective-C class implementation file, and this will only work if the callback is able to use a context pointer of some sort.
So imagine the C callback signature is like this:
void myCallback(void *context, int someOtherInfo);
Then within the Objective-C class implementation file you need to use that callback to trampoline back into your Objective-C class (using the context pointer as the instance of the class to invoke):
// Forward declaration of C callback function
static void theCallbackFunction(void *context, int someOtherInfo);
// Private Methods
#interface MyClass ()
- (void)_callbackWithInfo:(int)someOtherInfo;
#end
#implementation MyClass
- (void)methodToSetupCallback
{
// Call function to set the callback function, passing it a "context"
setCallbackFunction(theCallbackFunction, self);
...
}
- (void)_callbackWithInfo:(int)someOtherInfo
{
NSLog(#"Some info: %d", someOtherInfo);
}
#end
static void theCallbackFunction(void *context, int someOtherInfo)
{
MyClass *object = (MyClass *)context;
[object _callbackWithInfo:someOtherInfo];
}
If your C callback function does not accept some sort of context info, then:
It's broken and this should be fixed/reported as a bug.
You will need to rely on storing a pointer-to-self at global, static, scope to be used by the C callback function. This will limit the number of instances of MyClass to one!

Emulating public/protected static vars in Objective-C

The top voted answer to this SA question ( Objective C Static Class Level variables ) outlines my question quite well but to it, I'd like to add one more criteria:
Issue Description
You want your ClassA to have a ClassB class variable.
You are using Objective-C as programming language.
Objective-C does not support class variables as C++ does.
I want to access ClassA's class variable from subclass ClassASub
or even better
4a. I want ClassA's method to access the class variable as it is, overridden in ClassASub
Any ideas? Or is this just bending Objective-C one step too far?
Just make a normal getter method for your class variable, and you can override it in the subclass. Just remember to access it through the method.
static SomeClass *gClassVar;
#implementation ClassA
+ (SomeClass *)classVar {
if (!gClassVar)
gClassVar = ...;
return gClassVar;
}
+ (...)someMethod {
[[self classVar] doSomething];
}
#end
Then,
static SomeClass *gClassVar;
#implementation ClassASubclass
+ (SomeClass *)classVar {
if (!gClassVar)
gClassVar = ...;
return gClassVar;
}
#end
So, when you call [ClassA someMethod], it will operate on the ClassA instance of classVar. When you call [ClassASubclass someMethod], it will operate on the ClassASubclass instance.
The idea of having variables of any sort attached to an object (class or instance) is a feature that is kind of "stapled on" to Objective C. Any time you want to do anything object-oriented using Objective C, start by working with methods. (Almost) everything else is just syntactic sugar for things you can do with methods.
The concept of private / protected / public is somewhat alien to Objective C, even though access control is supported for member variables. The best you can do for methods is to define them in a separate header (and this applies to class variables and properties, if we implement both using methods).

Call a variable from one file to the other

Of Objective C, I'm looking to call a variable from one .m to the other .m
This is given myvar declared as an int in Example1.h
Example1.m
myvar = myvar+10
Example2.m
if (myvar == 10){NSLOG("#myvar equals the correct integer: %i",myvar);}
However, by default myvar will equal 0 because myvar is called from Example1.h in Example2.m.
For global values, create a class to hold these and define the variables as static. You can also define class level methods to manipulate the static variable. I call my class appState. You might define myVar as static and then class methods (use the + not -) to get and set this variable.
Here's an example of a BOOL I can access from anywhere in my application.
account.h
#import <Foundation/Foundation.h>
#interface Account : NSObject
{
}
+(BOOL)isOffLine;
+(void)setOffLine:(BOOL)newValue;
#end
account.m
#import "Account.h"
#implementation Account
static BOOL _offline;
+(BOOL)isOffLine;
{
return _offline;
}
+(void)setOffLine:(BOOL)newValue
{
_offline = newValue;
}
#end
Now from any class in my application, I can #import account.h and then use something like:
if ([Account isOffLine]) {...}
or
[Account setOffLine:YES];
Note that I didn't create an instance of this class. I'm calling the class level methods. The value will persist between calls from different classes in my application.
I’d recommend you read up on the basics, perhaps Object-Oriented Programming with Objective-C could be a good place to start. My guess is that what you really should be doing is creating a property in one class and accessing it from another.

ivars when mixing C and Objective-C

I'm writing an Objective-C wrapper for a C library and having problems accessing the references of my ivars.
The C library requires that I specify a function pointer that handles events, I specify it during the initialization of my Objective-C class.
- (id) init {
[super init];
RegisterClient(&handleEvent);
return self;
}
The C library is able to start searching for something and will then call the handleEvent function in case anything happened during the search. The function (basically) looks like this.
int handleEvent(void *Event) {
[delegate didFinishSearching];
return 0;
}
At least I'd wish it looked like this. The problem is that the code won't build because 'delegate' undeclared (first use in function) (of course I have declared it, I can call [delegate didFinishSearching] from any Objective-C method but not from a C function). Older questions from stackoverflow suggest to define an additional variable (e.g. theDelegate) in the header file:
id theDelegate;
#interface Controller : NSObject {
id delegate;
}
#property (assign) id delegate;
#end
Then, whenever I change the value of delegate to a new one, I have to assign this value to theDelegate, too.
Since my C is somewhat rusty, here are my questions:
1) Can I pass the RegisterClient C function a pointer to an Objective-C method instead of a pointer to a function as an argument in order to avoid the C function handleEvent completely?
2) If not: When I create multiple instances of this Objective-C class, will theDelegate be the same for all instances? (After all, it's not declared as an instance variable...)
Objective-C methods are C functions, but they have two hidden parameters at the front, so they won't have the int f(void *) signature.
What you probably want to do is use an libffi closure. That allows you to create a function with exactly the signature that you want, but that also has a pointer to your object passed along with it. See the example in the ffi_prep_closure man page. Your handleEvent function would probably then change to look something like this:
static void handleEventClosure(ffi_cif * cif, void * result, void ** args, void * userdata)
{
// Arguments.
void * Event = *args[0];
// Closed-over data.
id delegate = (id)userdata;
// Execute the method.
[delegate didFinishSearching];
// Smaller than sizeof(long), so use ffi_arg or ffi_sarg (unsigned or signed).
*(ffi_sarg *)result = (ffi_sarg)0;
}
Most of the time C Libraries like the one you describe accept a "userinfo" parameter conveniently size to match a pointer. You can use this to your advantage by passing your object as this "userinfo" parameter.
Then in callbacks, you cast the pointer back to an object and make the calls you need.