Compile Arm Assembly directly in XCode - iphone

What is the best way to go about compiling arm assembly code into xcode. I have those assembly files which are generated. Is there a way i can just include the .s file directly into the c code that i have. Or i will need to run an preprocessor first which would generate the .o file which i can link with my files. If that is the case, how do you do it in XCode.

If you could post the exact compiler error xcode is spitting out then I might be able to come up with a better solution but my guess as of now is that you are forgetting to add the _ prefix do you functions in assembly.
.globl _add_in_asm
_add_in_asm:
add r0,r0,#1
bx lr
Now in the C source file
#include <stdio.h>
extern int add_in_asm(int i);
int main(int argc, char* argv[]) {
printf("result:%i\n", add_in_asm(10));
return 0;
}
The program should print
result:11

It appears that you just need to add the .s file into your project. Converting it into inline assembly for C is possible, but also fairly difficult, so I recommend against it.

If you are having linking problems, remember Mach-O will be looking for the assembly methods to be prefixed with underscore. #A Person's example shows this, but does not point it out.
C-declaration
extern int add_in_asm(int i);
links against ASM method:
_add_in_asm

That is the first google result and whilst the answer is good, the actual way for me to do it is (Xcode 7.3.1; using real device)
under Xcode add an empty assembly file and use the code as above but add align statement
.globl _add_in_asm
.align 4
_add_in_asm:
add r0,r0,#1
bx lr
in the AppDelegate.m
add
include <stdio.h> and
under the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
extern int add_in_asm(int i);
printf("result:%i\n", add_in_asm(10));
Having said that and after it was successfully run, it does not work after I close Xcode and restart it ... well one has to use real device and when restart, it would try to use emulator!!!!
`
/Users/xxx/Documents/myMac-git/testasm/my-testasm.s:18:11: error: invalid operand for instruction
add r0,r0,#1
^
/Users/xxx/Documents/myMac-git/testasm/my-testasm.s:19:7: error: unrecognized instruction mnemonic
bx lr
^
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1
`
If you see above message use real devices!

Related

How do you call a C function from C++ code in the iPhone?

I added the line extern "C" void perlinTest(void); to a C++ header along with the include of the c header file hoping that was all I needed but the compiler complains:
Undefined symbols for architecture i386:
"perlinTest()", referenced from:
CreateRenderer3(IResourceManager*) in Renderer.o
Your C++ code needs to be aware that the function is a C function. To do so, you need to declare it this way:
extern "C" [prototype];
A realistic example for your situation would be:
extern "C" void perlinTest();
The reason for this is that C++ function names are mangled to something that tells about the types of the parameters. At the lowest level, this is what allows overloading: it never really is legal to have two visible symbols that share the same name, so C++ allows them by embedding markers that indicate the types of the parameters in the function names. For instance, void perlinTest() gets mangled as _Z10perlinTestv on my Lion box with g++ (and probably clang++), though this is ABI-specific and will not necessarily be the same on other platforms.
However, C doesn't support overloading, and functions aren't subject to name mangling, so when your C++ code tries to call one, it needs to know that it must not use a mangled name. This is what extern "C" tells the compiler.
If your header files need to be readable from both C and C++, the common practice is to wrap them in an extern "C" block (extern "C" { /* declarations */ }) itself wrapped in an #ifdef __cplusplus preprocessor directive (so the C code doesn't see the extern "C" code).
#ifdef __cplusplus
extern "C" {
#endif
/* header body */
#ifdef __cplusplus
}
#endif
If it is not a library, you do not need any extern C. Iwould be turning to the .c file extensions and how your compiler is configured to recognize it (looks like not as .c code)
Have you actually implemented void perlinTest(void) anywhere?
Initially, you'll likely be able to merely declare the function without actually having to implement it. If none of your other classes/objects actually call perlinTest(), Xcode will gladly build and run your app, and not issue any errors. Since perlinTest() isn't actually referenced from anywhere, it doesn't care that the function isn't actually implemented.
As soon as you attempt to call perlinTest() from one of your other classes (like from CreateRenderer3(IResourceManager*) in Renderer.o), the linker will want to make sure that symbol can be resolved, and if you haven't actually implemented a barebones definition of it (see below), then you'll likely get an error like the one you got.
A minimal implementation like the following should prevent the linking error:
void perlinTest(void) {
}
One trick you can use to debug this is to introduce an intentional error in your perlinTest() function. Then build your app and see if the compiler reports the error. If the app compiles anyway, then your problem is that the file that has this function is not part of the target you are building.
Also note that the error that you pasted is for a i386 architecture, so it can't be iPhone. You are probably building for the iPhone simulator instead.
Edit: next step would be to check that the link command issued by Xcode includes the .o that has the C function. If it does, then you should dump the contents of the .o file with the nm utility, to see what the function name looks like in the .o.

How to use Grand Central Dispatch in iOS in a .c file

I have some C code in an iOS project that I would like to optimize using GCD. Currently I can only get my code to compile if change my C file to an Objective-C file and import the Foundation framework. What do I have to include in my C file to get access to GCD?
I've tried:
#include <dispatch/dispatch.h>
but that doesn't seem to work it always complains about code blocks having the ^ character
You'll need to tell the compiler to enable Blocks with the -fblocks flag. You'll also need to use a compiler that understands blocks (Clang, for one).
You might need to;
#include <Block.h>
But it's not something I've done myself so could be wrong here.

Can't build objective-c project when including Foundation

Sorry in advance if this has been answered, I've searched repeatedly here and the in the apple docs, but haven't found out what is causing this problem. I have a iOS app that is driven by a 'layout' file that contains references to the content. I wanted to create a command line tool to optimize the content and modify the layout file if need. For example, by tiling an image and replacing it in the layout by the tiles.
I thought to create my first ever OSX tool and used the newest Xcode to create a CoreFoundation project, which gives me a main.c like this:
#include <CoreFoundation/CoreFoundation.h>
int main (int argc, const char * argv[])
{
CFShow(CFSTR("Hello, World!\n"));
return 0;
}
which builds fine. I thought to use some of the NS* classes to start working with the command line args, but as soon as I included the Foundation framework and added this line:
#include <Foundation/Foundation.h>
I started to get tons of build errors. I think I'm missing something basic, here, but I can't see it! Did I choose the wrong template? Is there a better one? Or, what's the problem with using Foundation here?
You need to set the file language to Objective C for it to compile. Either that or rename main.c in main.m

Compiling C with Objective-C and duplicate symbol linker error (iPhone related)

I have the following file testf.h:
#ifndef TESTF_H_
#define TESTF_H_
int test(int what){
return what;
}
#endif
I included/imported it in TestAppDelegate.h (which is used for other .m files in my xcode project). I get a duplicate symbol error. If I included/imported testf.h in a .m file that is never included/imported in other files then it works fine. So it seems like the #ifndef/#define/#endif has no effect. Is there anyway to go around this?
Thanks
This is a function definition, it belongs in a c, cpp or m file.
This popular trick with #defines will protect you from compiler errors (typically to survive circular #include dependencies. ) It will not protect against a linker error. This is exactly why people put declarations in h files and definitions in c (or m) files.
Including function definitions (as opposed to declarations) in header files is generally a bad idea and now you know why. You want two separate files, the header would look like this:
#ifndef TESTF_H_
#define TESTF_H_
extern int test(int);
#endif
And then a .c file (or possibly a .m file if you want to use Objective-C rather than plain C) like this:
int test(int what) {
return what;
}
The header file will let the compiler know what test is, what it returns, and what arguments it should take; that's enough information for the compiler to arrange a call to test; that's actually more information than the compiler needs but some of us like our compilers to do some error checking. The C source file will (after being compiled into a object file) let the linker know what code the test symbol resolves to.
Right now you're ending up with multiple globally visible instances of the test symbol, one for every file that has included your testf.h.
The other option, for a simple function, is to declare it inline:
inline int cNorm(float _amp) {
return 42;
}

Typedef for STL Vector does not compile in XCode

I have some code written in C++ which I would like to use in my iPhone app. I added the source files to the XCode project, but I have problem with some parts of the source code, e.g. I have he following code:
#import <vector>
// (...) some other code
typedef std::vector<keypoint> keypointslist;
// (...) rest of the code
In the line with the typedef I'm getting:
Expected '=', ',', ';', 'asm' or 'attribute' before ':' token in
Exactly the same code was compiled with gcc on Linux machine, so I wonder why XCode has problem with it.
Any suggestions?
Are you sure, you told XCode to compile the file as C++ and not as C or Objective-C? Maybe you must use the file extension ".cpp".
It's called #include, not #import:
#include <vector>
+1 with Ludger,
youre adding that to an objective c app, you'll need to add a .cp/.mm/.cpp translation unit to the project to get that to compile - right click on project classes select add class make sure you add one from the cpp section.
If you include C++ code in a ".m" file you must rename the extension to ".mm" or ".M". this applies even if you reference a C++ class from an objective C one, the file must be renamed. Sometimes this renaming has a domino effect and so you end up with a lot of ".mm" files in your project.
Make sure you included <vector> header file before typedef. It looks like the compiler doesn't know std namespace.
You have to rename the ALL files that use the C++ code with .mm extension.
That includes your view controller files that could be importing the C++ class. eg. MyViewController.mm