Whats the scope of a c function defined within objective-c class? - c

I was reading up about bypassing objective-c's messaging to gain performance (irrelevant to this specific question) when i found an interesting bit of code:
#import <Cocoa/Cocoa.h>
#interface Fib : NSObject { }
- (long long) cFib: (NSUInteger) number;
#end
#implementation Fib
// c implementation of fib
long long cFibIMP(NSUInteger number)
{
return (number < 3) ? 1 : cFib(number - 1) + cFib(number - 2);
}
// method wrapper for c implementation of fib
- (long long) cFib: (NSUInteger) number
{
return cFibIMP(number);
}
#end
My question is; when using c function, within an objective-c object, what scope is the c function (cFibIMP in this particular case) placed in? Does the objective-c class encapsulate the c function removing change of name-clash or is the c function simply dumped into the global scope of the whole objective-c program?

The functions are dumped in the "global" scope.
You can check this by adding a new class at the end of your sample code:
#interface Gib : NSObject {}
#end
#implementation Gib
- (void) t
{
NSLog(#"%d", cFibIMP(10));
}
#end

The C function has global scope.
If you want to have something like "class" scope, your best bet is probably to use the static keyword, which limits the scope of the function to the source file in which it is contained. For the sort of usage you're illustrating here, that's usually close enough.

Related

C++11, wrapper class for handling different versions of C struct versions

EDIT:
I think the version is known at run-time instead of compile-time so I'm not able to add it as a compile option to the gcc cmd. Which is why I have to support both versions based on whatever version the hardware reports back.
So I'm dealing with firmware where I am required to support multiple definitions for versions of the same C struct. We created our own header file as defined by the interface documentation of a memory controller based on the vendor's C struct definition.
// For simplicity lets pretend that this is the struct for version 1
typedef struct __attribute__((packed)) ver1 {
int x;
int y;
} ver1;
I also have an existing API that uses this interface already that needs to be replaced by some sort of class wrapper (I believe), or a wrapper that plays well with the existing API.
void function_call(ver1 v1);
Only one instance (ver 1 or ver 2) of the struct can exist at any time
ver 1 for a certain fw version, and ver 2 after a certain fw version
ver2 is my extended version of ver1, I am naming it as ver2 for the hope of using some sort of factory to select the right C-style struct.
typedef struct __attribute__((packed)) ver2 {
int x;
int y;
int w; // new
int z; // new
} ver2;
Before creating a ver 2 I was looking into options such as the decorator or adaptor design pattern I could try a fancy CRTP template style I found on Hands-On Design Patterns but for simplicity, I'll illustrate with this scheme where I could possibly "add-on" to ver1:
struct ver2 : public ver1 {
int w;
int z;
}
But then I learned that C++ doesn't guarantee the same class layout
C struct Inheritance vs C++ POD struct Inheritance
and potential alignment issues (I'm not too familiar with it) so I don't think it is a real option for me to use.
I found this example on stackoverflow but I don't like the idea of adding include headers in the struct How to handle conflicting struct definitions in a C application.
There is a similar example here using a similar base class
C++ design for multiple versions of same interface (enumerations / structures in header files) which I don't think I can even use due to inheritance impact on the class layout.
Unless there is a valid reason to use the techniques of the links above, I was considering a wrapper class that returns the right version based on a selector. First I'll define a free function to leverage this.
int get_fw_version(int target);
I'm working on C++11 so I'm limited on auto return type deduction and below is just some draft code I'm trying to think up, not complete, doesn't compile, just illustrating my thought process. I haven't considered composition yet since IDK how that will quite work. Looking for ideas.
int main() {
// Roughly how I would like to use it...
const int fw_ver = get_fw_version(target);
auto ver_inst = ver_factory(fw_ver);
function_call( ver_inst.get_data() );
return 0;
}
I am not sure if I can do this without polymorphism where the base class gets ver1 and but the derived class has ver2.
Rough idea where I am at, I tried doing CRTP but I hit the problem that the base class needs to be a template and I can't use a heterogeneous base type (e.g. shared_ptr). Trying the non-CRTP way IDK how to set up the abstract base class with the get_data() method. Without the compiler complains saying that the base doesn't have a get_data method, which, makes sense
// I can't figure out how to add T get_data() here without adding a template param. This base function is really to delegate common member methods and trying to keep a common base for polymorphism.
class base {
virtual ~base() = 0;
// ?? get_data() = 0 or some other method
};
class ver1_derived : public base
{
ver1 data;
public:
ver1_derived() = default;
ver1 get_data() {
return data;
}
};
class ver2_derived : public base
{
ver2 data;
public:
ver2_derived() = default;
ver2 get_data() {
return data;
}
};
// should be using unique_ptr but I can't at work....
shared_ptr<base> ver_factory(const int fw_ver) {
if(fw_ver <= 1)
return make_shared<ver1_derived>();
return make_shared<ver2_derived>();
}
I ended up giving up on an inheritance schemed and ended up taking two different code paths based on the template type.
So
if(fw_ver <= 1)
function_call<ver1>();
} else {
function_call<ver2>();
}

How to call objective-C function from a C function

I'm trying to call an objective-C function from a C function but the code keeps crashing in objc_msgSend.
My objective-C class is a singleton and I'm using the following code.
void c_function(int arg0, const char *arg1)
{
[[objc_class instance] testFunction:arg0 Arg1:arg1];
}
The gdb shows the crash is happening when objective-C function is being invoked. How cal I call an objective-C function from within a c function?
Thanks
There's nothing wrong with your code as there are no special rules for calling objc methods from c functions. If there is a crash in objc_msgSend, then refer to http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html. The same thing would have happened if the objc line was in other objc code -- it's likely you forgot to retain the shared instance of your singleton.
[[objc_class instance] testFunction:arg0 Arg1:arg1];
As you don’t provide further information:
objec_class is an instance, your singleton? And it handles the message instance? …
or
objec_class is really a class, having a class method instance? And this will give you another instance …
In other words, do you really have something like
#interface class2 {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
and
#include "class2.h"
#interface objc_class {
}
-(class2*) instance {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
or
#include "class2.h"
#interface objc_class {
}
+(class2*) instance;
// be aware of the fact, instance (normaly) does not have
// access to any instance variables!
to be included?
Your code doesn’t look like „hey, object(instance) singleton, I tell you to ‘instance’. Then I take your response and give it the message ‘testFunction:Arg1:’ (with some values inserted)”!
(Are you sure you understood objective c?)
Greetings
1:
#interface class2 {
}
-(void) testFunction:(int)count Arg1:(const char *)args;
#end
2:
#include "class2.h"
#interface objc_class {
}
-(class2*) instance;
#end
3:
#include "class2.h"
#interface objc_class {
}
+(class2*) instance; // be aware of the fact, instance (normally) does not
// have access to any instance variables!

Embedding Ruby, calling a function from C

I'm writing an app that calls ruby code from c. I am having a little difficulty and wondered if anyone could point me in the rite direction.
I currently have in my C.
#include ruby.h
main()
{
ruby_init();
rb_require("myRubyFile");
rb_funcall(rb_module_new(), rb_intern("RubyFunction"), 0, NULL);
}
My ruby file is in the same directory as my c file and is called myRubyFile.rb and contains a definition of the function RubyFunction().
This is a cut down of what I actually want to do, just making it more readable for others. I just require some feedback as to whether this is the correct method to call ruby code from my c file.
Regards
Short answer:
extern VALUE rb_vm_top_self(void); /* Assumes 1.9. Under 1.8, use the global
* VALUE ruby_top_self
*/
...
rb_funcall(rb_vm_top_self(), /* irb> RubyFunction() */
rb_intern("RubyFunction"), /* irb> self.RubyFunction() # same thing */
0,
NULL);
Longer answer:
The first argument to rb_funcall is the receiver of the method call.
Assuming you defined RubyFunction() outside of any explicit class or module context, then it is added to the eigenclass of the implicit, main object at the "top level" of every ruby vm.
In ruby, this object is accessible as the top-level self:
$ cat myRubyFile.rb
# file: myRubyFile.rb
def foo
puts "foo"
end
$ irb
irb> require "myRubyFile"
=> true
irb> foo
foo
=> nil
irb> self.foo() # same thing, more explicit
foo
=> nil
irb> self
=> main
In C under 1.9 it is accessible as indicated above.
I try to use the following approach:
Basic struct to share data
typedef struct ruby_shared_data {
VALUE obj;
ID method_id;
int nargs;
VALUE args[4];
} ruby_shared_data;
Create a function for call ruby objects on some part of your code
static VALUE ruby_callback(VALUE ptr) {
ruby_shared_data *data = (ruby_shared_data*)ptr;
return rb_funcall2(data->obj,data->method_id,data->nargs,data->args);
}
On some part of your code...
ruby_shared_data rbdata;
rbdata.obj = obj;
rbdata.method_id = rb_intern("mycallback");
rbdata.nargs = 1;
rbdata.args[0] = rb_str_new2("im a parameter");
int error = 0;
VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);
if (error)
throw "Ruby exception on callback";
Is always a good idea to wrap rb_funcall with rb_protect.
Another interesting thing is to know the parameters of the callback, one approach is the following
ruby_shared_data rbdata;
rbdata.obj = callback;
rbdata.method_id = rb_intern("arity");
rbdata.nargs = 0;
int error = 0;
VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);
if (error)
throw "Ruby exception on callback";
narguments = NUM2INT(result);
I don't like to call ruby from inside C unless you have complex C project which you don't want to re-build in ruby.
There are two ways to interact between C and ruby. You can extend ruby with code written in C. See SWIG.
Or you can embed ruby, see here, here and here.
BTW, what do you mention is "embed" ruby, not "extend" ruby.

Mixing C functions in an Objective-C class

I am writing an Objective-C class but it uses an API written in C. This is mostly fine as mixing C calls with Objective-C calls causes few problems.
However one of the API call requires a call back method (example):
success = CFHostSetClient(host, MyCFHostClientCallBack, &context);
Where MyCFHostClientCallBack is a C function defined like this:
static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
Can/How do I call an Objective-C method in place of this?
Can/Should I mix C functions with my Objective-C calls?
How do I mix C functions with Objective-C methods?
Mixing C and Objective-C methods and function is possible, here is a simple example that uses the SQLite API within an iPhone App: (course site)
Download the Zip file (09_MySQLiteTableView.zip)
C functions need to be declared outside of the #implementation in an Objective-C (.m) file.
int MyCFunction(int num, void *data)
{
//code here...
}
#implementation
- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
//code here
}
#end
Because the C function is outside of the #implementation it cannot call methods like
[self doSomething]
and has no access to ivars.
This can be worked around as long as the call-back function takes a userInfo or context type parameter, normally of type void*. This can be used to send any Objective-C object to the C function.
As in the sample code, this can be manipulated with normal Objective-C operations.
In addition please read this answer: Mixing C functions in an Objective-C class
To call Objective-C code from a C callback I would use something like:
void * refToSelf;
int cCallback()
{
[refToSelf someMethod:someArg];
}
#implementation SomeClass
- (id) init
{
self = [super init];
refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
Can/How do I call an Objective-C method in place of this?
You cannot.
Can/Should I mix C function in with my Objective-C call?
Yes. Write a C function and use that as the callback to the CF function.
How do I mix C function with Objective-C methods?
You can set self as the info pointer in your context structure. That will be passed to the callback. Then, in the callback, cast the info pointer back to id:
MyClass *self = (id)info;
You can then send self messages. You still can't directly access instance variables, though, since a C function is outside of the #implementation section. You'll have to make them properties. You can do this with a class extension. (Contrary to what that document says, you would not declare the extension inside #implementation, but in the same file with it, generally right above it.)
What I've always found helpful in this situation is to make an Obj-C wrapper on top of the C API. Implement what you need to using C functions, and build an Objective-C class (or two) on top of it, so that's all the outside world will see. For example, in the case of a callback like this, you might make a C function that calls Obj-C delegate methods on other objects.
.m call function inside .c:
CrifanLib.h
#ifndef CrifanLib_h
#define CrifanLib_h
#include <stdio.h>
void fileModeToStr(mode_t mode, char * modeStrBuf);
#endif /* CrifanLib_h */
CrifanLib.c
#include "CrifanLib.h"
#include <stdbool.h>
void fileModeToStr(mode_t mode, char * modeStrBuf) {
// buf must have at least 10 bytes
const char chars[] = "rwxrwxrwx";
for (size_t i = 0; i < 9; i++) {
// buf[i] = (mode & (1 << (8-i))) ? chars[i] : '-';
bool hasSetCurBit = mode & (1 << (8-i));
modeStrBuf[i] = hasSetCurBit ? chars[i] : '-';
}
modeStrBuf[9] = '\0';
}
called by Objective-C's .m:
#include “CrifanLib.h"
#interface JailbreakDetectionViewController ()
#end
#implementation JailbreakDetectionViewController
…
char* statToStr(struct stat* statInfo){
char stModeStr[10];
fileModeToStr(statInfo->st_mode, stModeStr);
...
}
...
done.

How to create a Singleton in C?

What's the best way to create a singleton in C? A concurrent solution would be nice.
I am aware that C isn't the first language you would use for a singleton.
First, C is not suitable for OO programming. You'd be fighting all the way if you do. Secondly, singletons are just static variables with some encapsulation. So you can use a static global variable. However, global variables typically have far too many ills associated with them. You could otherwise use a function local static variable, like this:
int *SingletonInt() {
static int instance = 42;
return &instance;
}
or a smarter macro:
#define SINGLETON(t, inst, init) t* Singleton_##t() { \
static t inst = init; \
return &inst; \
}
#include <stdio.h>
/* actual definition */
SINGLETON(float, finst, 4.2);
int main() {
printf("%f\n", *(Singleton_float()));
return 0;
}
And finally, remember, that singletons are mostly abused. It is difficult to get them right, especially under multi-threaded environments...
You don't need to. C already has global variables, so you don't need a work-around to simulate them.
It's the same as the C++ version pretty much. Just have a function that returns an instance pointer. It can be a static variable inside the function. Wrap the function body with a critical section or pthread mutex, depending on platform.
#include <stdlib.h>
struct A
{
int a;
int b;
};
struct A* getObject()
{
static struct A *instance = NULL;
// do lock here
if(instance == NULL)
{
instance = malloc(sizeof(*instance));
instance->a = 1;
instance->b = 2;
}
// do unlock
return instance;
};
Note that you'd need a function to free up the singleton too. Especially if it grabs any system resources that aren't automatically released on process exit.
EDIT: My answer presumes the singleton you are creating is somewhat complex and has a multi-step creation process. If it's just static data, go with a global like others have suggested.
A singleton in C will be very weird . . . I've never seen an example of "object oriented C" that looked particularly elegant. If possible, consider using C++. C++ allows you to pick and choose which features you want to use, and many people just use it as a "better C".
Below is a pretty typical pattern for lock-free one-time initialization. The InterlockCompareExchangePtr atomically swaps in the new value if the previous is null. This protects if multiple threads try to create the singleton at the same time, only one will win. The others will delete their newly created object.
MyObj* g_singleton; // MyObj is some struct.
MyObj* GetMyObj()
{
MyObj* singleton;
if (g_singleton == NULL)
{
singleton = CreateNewObj();
// Only swap if the existing value is null. If not on Windows,
// use whatever compare and swap your platform provides.
if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
{
DeleteObj(singleton);
}
}
return g_singleton;
}
DoSomethingWithSingleton(GetMyObj());
Here's another perspective: every file in a C program is effectively a singleton class that is auto instantiated at runtime and cannot be subclassed.
Global static variables are your private class members.
Global non static are public (just declare them using extern in some header file).
Static functions are private methods
Non-static functions are the public ones.
Give everything a proper prefix and now you can use my_singleton_method() in lieu of my_singleton.method().
If your singleton is complex you can write a generate_singleton() method to initialize it before use, but then you need to make sure all the other public methods check if it was called and error out if not.
I think this solution might be the simplest and best for most use cases...
In this example, I am creating a single instance global dispatch queue, which you'd definitely do, say, if you were tracking dispatch source events from multiple objects; in that case, every object listening to the queue for events could be notified when a new task is added to the queue. Once the global queue is set (via queue_ref()), it can be referenced with the queue variable in any file in which the header file is included (examples are provided below).
In one of my implementations, I called queue_ref() in AppDelegate.m (main.c would work, too). That way, queue will be initialized before any other calling object attempts to access it. In the remaining objects, I simply called queue. Returning a value from a variable is much faster than calling a function, and then checking the value of the variable before returning it.
In GlobalQueue.h:
#ifndef GlobalQueue_h
#define GlobalQueue_h
#include <stdio.h>
#include <dispatch/dispatch.h>
extern dispatch_queue_t queue;
extern dispatch_queue_t queue_ref(void);
#endif /* GlobalQueue_h */
In GlobalQueue.c:
#include "GlobalQueue.h"
dispatch_queue_t queue;
dispatch_queue_t queue_ref(void) {
if (!queue) {
queue = dispatch_queue_create_with_target("GlobalDispatchQueue", DISPATCH_QUEUE_SERIAL, dispatch_get_main_queue());
}
return queue;
}
To use:
#include "GlobalQueue.h" in any Objective-C or C implementation source file.
Call queue_ref() to use the dispatch queue. Once queue_ref() has been called, the queue can be used via the queue variable in all source files
Examples:
Calling queue_ref():
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue_ref()**);
Calling queue:
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue**));]
Just do
void * getSingleTon() {
static Class object = (Class *)malloc( sizeof( Class ) );
return &object;
}
which works in a concurrent environment too.

Resources