PDA

View Full Version : Problems mixing C and OBJ-C




Nixarn
Aug 27, 2008, 09:52 AM
Heya!

Yet another noob to OBJ-C and iPhone programming. Although not a newby when it comes to programming in general.

Never been a big mac fan, but the iPhone 3G was too good not to get. And that got me to lend a Mac mini to do some coding for it. Maybe I'll turn into a mac-guy one day :O

Anyway, right to the point. I'm making a game and to avoid getting too deep into OBJ-C I decided to stick with more C than OBJ-C. Now I wanted to load some resources, but to get the path to the resource I apparently needed some OBJ-C:

fileString = (CFStringRef)[[NSBundle mainBundle] pathForResource:@"FileName" ofType:@"ext"];

Well, the problem is that when I include stuff like UIKit to get that line to compile I get all kind of weird errors. Inporting UIKit in my C header gives me > 1000errors.


/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:120: error: syntax error before '@' token
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:122: error: syntax error before '*' token
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:123: error: syntax error before '*' token
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:125: error: syntax error before '*' token
etc....



What am I doing wrong?

Thanks in advance!

Nixarn



davedelong
Aug 27, 2008, 10:14 AM
I'm making a game and to avoid getting too deep into OBJ-C I decided to stick with more C than OBJ-C. Now I wanted to load some resources, but to get the path to the resource I apparently needed some OBJ-C.

...

What am I doing wrong?

At the risk of sounding snide, I'd say what you're doing "wrong" is trying to avoid using Objective-C. The Frameworks are there for a reason, and Apple spends more time designing them than actually writing them. You can easily get back and NSString from your NSBundle -pathForResource: ofType: method, and then use the NSString to init a new object (whether an image or whatever).

Don't fight the frameworks. You won't win. :)

Good luck, and I hope you can figure out what you're looking for. PM me if you want some good starting points on getting used to Objective-C and the frameworks.

Dave

robbieduncan
Aug 27, 2008, 10:34 AM
Is that is a .c or a .m file? I'm pretty sure you can only use Obj-C in .m files...

davedelong
Aug 27, 2008, 10:37 AM
Ignore this post

Nixarn
Aug 27, 2008, 10:50 AM
Thanks guys! Going OBJ-C wasn't the quick fix I was looking for ;)

It's a .c file so I'll try a .m file. I do intend to use OBJ-C for some stuff, but coding some of the basic engine stuff in C felt like a good idea as it's portable.

I got Cocoa Programming For Mac OS X third edition to learn OBJ-C, so I'm not completely fighting it, just wanted to chose an easy path ;)

Nixarn

EDIT: Renaming it to .m worked! Thanks!

robbieduncan
Aug 27, 2008, 10:54 AM
just wanted to chose an easy path ;)

You are actually choosing the insanely hard path. If you actually stick to using Objective-C and the frameworks as much as possible you'll write less code...

Ron C
Aug 27, 2008, 02:15 PM
You are actually choosing the insanely hard path. If you actually stick to using Objective-C and the frameworks as much as possible you'll write less code...

I don't disagree when the frameworks actually provide what you want.

So which framework provides a FFT? I have C code for it, but I don't have Obj-C.

(If you don't know what a FFT is, then you should skip this question ;) )

Ron C

davedelong
Aug 27, 2008, 02:43 PM
So which framework provides a FFT? I have C code for it, but I don't have Obj-C.

Some googling has hinted that the CoreAudio and Accelerate frameworks have FFT.

Ron C
Aug 27, 2008, 04:51 PM
Some googling has hinted that the CoreAudio and Accelerate frameworks have FFT.
Hmm. I checked the CoreAudio framework documentation but neither the term FFT nor DFT shows up (specifically, I looked at the Core Audio Overview (http://developer.apple.com/iphone/library/documentation/MusicAudio/Conceptual/CoreAudioOverview/CoreAudioOverview.pdf) and very little else for Core Audio).

Then I thought I'd try what you tried. I google'd "FFT iPhone" and found this (http://www.iphonedevsdk.com/forum/iphone-sdk-development/1420-fft-apis.html).

Sounds like I should just use my C routine :(

Ron C

Likewise for

ploppy
Aug 27, 2008, 06:28 PM
Hmm. I checked the CoreAudio framework documentation but neither the term FFT nor DFT shows up (specifically, I looked at the Core Audio Overview (http://developer.apple.com/iphone/library/documentation/MusicAudio/Conceptual/CoreAudioOverview/CoreAudioOverview.pdf) and very little else for Core Audio).

Then I thought I'd try what you tried. I google'd "FFT iPhone" and found this (http://www.iphonedevsdk.com/forum/iphone-sdk-development/1420-fft-apis.html).

Sounds like I should just use my C routine :(

Ron C

Likewise for

Accelerate.framework is only available on the Mac, and CoreAudio has nothing to do with FFT.

Remember, you're writing for a mobile device powered from a battery, not something that has access to all the power it wants. So instead of using your C routine which gcc won't optimize very well, it'll definitely be better to use an FFT specially written for the iPhone's processor.

ARM has a decent free library containing (among other things) an FFT optimized for ARMv6 here: http://www.arm.com/products/multimedia/openmax/v6libraries.html

The stuff you want is in the sp folder. However, you WILL need to work the code around a bit to get it to work on the iPhone - it's written for ARM's RealView assembler, and also the function-calling conventions on the iPhone are a bit different from those of the official ARM ABI. You'll also need to turn off "compile for Thumb" in Xcode.

Unfortunately, it's only fixed-point yet the iPhone's processor has a VFP unit. You might want to write your own ARMv6 VFP floating-point FFT. ARM assembly is fun! (really!)

robbieduncan
Aug 28, 2008, 02:23 AM
I would use your C routine for your FFT, but it would probably be the only pure-C function in your application!

Your initial example where you are getting a CFString to load a file for example: I would use the frameworks to load the file. I'd not try and use C directly...

Ron C
Aug 28, 2008, 10:26 AM
I would use your C routine for your FFT, but it would probably be the only pure-C function in your application!

Your initial example where you are getting a CFString to load a file for example: I would use the frameworks to load the file. I'd not try and use C directly...

(Editorial note: It wasn't *my* initial example, it was Nixarn's)

That minor comment notwithstanding, I agree that when there is an appropriate framework function to do something (key word here is appropriate) then that probably should be used. There are several examples in this forum of questions of the form:

How can I do X? (or "Is there a function that does X?") - see this thread.
I want to do something just like this, but different (see this thread for a recent example).
I have code that does X. How do I do that on the iPhone?

Perhaps this is immaturity with the APIs by this community, perhaps it is that the APIs are complex, and perhaps it's because it's hard to search the API documentation. More likely, it's all three conspiring.

There's another, probably more important, element of frameworks that comes into play - frameworks are purposefully limiting. They describe and implement things in a certain way, making it easy to change in certain dimensions and less easy in others. If what you want to do aligns with that way, then the framework feels natural and easy. If you want to do something slightly different, then you encounter resistance in the framework. If you want to do something very different, you will find the framework almost as your enemy, impeding you at every turn. If you want to do something outside the scope of the framework (e.g., the FFT) you will find neither help nor resistance from the framework (yet somehow I always seem both surprised and disappointed when this happens; afterwards it's pretty easy to see that it's just not part of the scope of the system, but that's after a few beers usually ;)).

My particular example (the FFT) is purposefully argumentative - I chose something that I expected NOT to exist on the iPhone that I would want to use in an applications AND that I already have the code to do. I won't share (yet) why I might want a FFT, but it's not for processing audio. I don't anticipate having to do this in real-time, so I'm not entirely concerned (yet?) about execution speed, but I may become so after seeing it take a week to run.

Nonetheless I enjoy the discussion when it's above the level of the "write my code for me" question though.

Ron C

spt.tps
Aug 29, 2008, 12:04 AM
Here is something to try.

1) rename the cocoa file that calls your c code to have .mm extension rather than .m

And

2) Either translate your c code to c++, and rename your .cpp to end with .mm extension

3) Or enclose your c code with extern "C" { .... code .... } and end that file name with .mm extension

SenatorOmelet
Oct 31, 2008, 01:25 AM
First of all, Accelerate.framework and veclib.framework are private frameworks in iPhoneOs2.x -- Apple will probably reject any App Store submission that links against them.

I love Objective-C and have been coding it for 18 years. However, it is really important to isolate computationally intensive code into vanilla c blocks or functions. Since Objective-C is a dynamic language, there is a lot of overhead incurred for every method invocation -- even considering caching. It does not make sense to invoke a nest of method calls in the middle of an audio processing routine for example.

Use Objective-C whenever appropriate -- using too little will probably demand you to reinvent many different wheels. Using too much in the wrong places can make your code sluggish. It is definitely a balancing act but you definitely can get the best of both worlds.