tags:

views:

774

answers:

2

Hi, In an Xcode project I have a C file with functions, it compiles and works OK

I want to wrap my C code in struct(s), how will I be able to call them in Objective-C?

+7  A: 

Objective-C is a proper superset of C. Anything you can do in C can be done identically in Objective-C. So, you really don't need to think of them as different languages; Objective-C is simply "C plus some more stuff".

// this struct is compatible with C and Obj-C
struct fruit {
    int a;
};

int main()
{
    struct fruit apple;
    apple.a = 1;

    return 0;
}

Then, any C or Objective-C source file can access that struct. There aren't any additional complications introduced by Objective-C.

Luca Matteis
Good answer. (To be clear, though, you don't call a struct.)
Jonathan Sterling
+1  A: 

Declare function pointers, add them to your structure and then call them, it's just C.

Example:

//Typedef 2 function pointers, first takes and returns int,
// second takes and returns double
typedef int    (*FuncPtrInt)   (int);
typedef double (*FuncPtrDouble)(double);

// create structure to store function pointers
struct ABC
{
    FuncPtrInt    applyA;
    FuncPtrDouble applyB;
};

// create some functions to use with structure
int incrFuncA(int num) { return ++num; }
double decrFuncB(double num) { return --num; }
double multiplyFuncB(double num) { return num*num; }

// try it out
void testStruct()
{
    struct ABC abc;
    abc.applyA = incrFuncA;
    abc.applyB = decrFuncB;

    NSLog(@"increment: %d",abc.applyA(3));
    NSLog(@"decrement: %f",abc.applyB(3.5));

    abc.applyB = multiplyFuncB;

    NSLog(@"multiply: %f",abc.applyB(3.5));
}

Output:

2010-02-01 10:36:22.335 x[11847] increment: 4
2010-02-01 10:36:22.336 x[11847] decrement: 2.500000
2010-02-01 10:36:22.336 x[11847] multiply: 12.250000

If you want to have a struct with functions where functions operate on the structure you have to pass the pointer to that function by default (similar to what c++ does):

Define:

struct ClassABC;
typedef int (*FuncPtrClassABC)(struct ClassABC *);
typedef int (*FuncPtrClassABCInt)(struct ClassABC *, int);

int incrFunc(struct ClassABC * abc);
int decrFunc(struct ClassABC * abc);
int addFunc(struct ClassABC * abc, int num);
int subtractFunc(struct ClassABC * abc, int num);

struct ClassABC
{
    int i;
    FuncPtrClassABC    increment;
    FuncPtrClassABC    decrement;
    FuncPtrClassABCInt add;
    FuncPtrClassABCInt subtract;
};

As you can see these functions could be standalone, you would still pass the ClassABC in:

int incrFunc(struct ClassABC * abc) { return ++(abc->i); }
int decrFunc(struct ClassABC * abc) { return --(abc->i); }
int addFunc(struct ClassABC * abc, int num)
{ abc->i += num; return abc->i; }
int subtractFunc(struct ClassABC * abc, int num)
{ abc->i -= num; return abc->i; }

Initialization helper func:

void initClassABC(struct ClassABC * abc)
{
    abc->i = 0;
    abc->increment = incrFunc;
    abc->decrement = decrFunc;
    abc->add = addFunc;
    abc->subtract = subtractFunc;
}

Usage:

struct ClassABC cabc;
initClassABC(&cabc);

cabc.add(&cabc,4);
NSLog(@"add: %d", cabc.i);

cabc.decrement(&cabc);
NSLog(@"decrement: %d", cabc.i);

cabc.subtract(&cabc,2);
NSLog(@"subtract: %d", cabc.i);

Output:

2010-02-01 10:56:39.569 x[12894] add: 4
2010-02-01 10:56:39.569 x[12894] decrement: 3
2010-02-01 10:56:39.569 x[12894] subtract: 1

Enjoy

stefanB
In the second case the functions could be standalone but because you were after wrapping code in structures then that's one way of doing it.
stefanB
You could use objective-c++ in that case I think you can just use c++ structures where methods have access to struct variables like in c++ class/struct.
stefanB