Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build and use a C++ static library for ios application

I know how to build a object C static library using iOS->Framework&Library->Cocoa Touch Static Library in xcode 4.6, and it is straightforward with the help of this tutorial Creating a Static Library in iOS Tutorial. One thing I am not sure, however, is how to build and use a pure C++ static library for io application. For building a C++ static library, I am also use iOS->Framework&Library->Cocoa Touch Static Library guideline, and the difference is that I delete all the .h and .m files when creating the static library project and then put all the C++ static library head files and implementation files in the project. A very simple example is as follows:

hello.h

#include <iostream>
void say_hello();

hello.cpp

#include "hello.h"

void say_hello()
{
std::cout<<"hello"<<std::endl;
}

It seems working, and I can build hello.a static library for iPhone 6.1 Simulator. The next step is to build an application that will invoke the static library. I build a simple iOS application->Single View Application for iPhone 6.1 Simulator, and then try to invoke the hello.a static library in ViewController.mm file (change ViewController.m to ViewController.mm so that it can invoke C++ function) simply with the following code:

say_hello();

However, I received one warning and two error messages:

Warning:

ld: warning: ignoring file hello.a, file was built for archive which is not the architecture being linked (i386): 

Error 1:

hello.a
Undefined symbols for architecture i386:
  "say_hello()", referenced from:
      -[ViewController viewDidLoad] in ViewController.o

Error 2:

ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I then have several questions related to this experiment:

  • Is it the right way to create a pure C++ static library?
  • Is there something wrong with the way how I invoke the C++ static library?

  • In my example, when invoking the static library, how could I solve the link errors?

Many thanks.

like image 208
feelfree Avatar asked Sep 15 '13 09:09

feelfree


3 Answers

This will do,

1)Create c++ library using same way, iOS->Framework&Library->Cocoa Touch Static Library in Xcode 6.

TestCPlusPlus.h

int sub(int a, int b);

TestCPlusPlus.cpp

int sub(int a, int b)
{
 return a - b;
}

2) Build the static library keeping configuration iOS Device, then iPhone 6(Basically simulator.)

3) then Expand Products in File Browser view. Select your .a file, say libTestStaticLibrary.a , then Right Button > Show in Finder. Move up in folders. You should be able to see two folers Debug-iphoneos and Debug-iphonesimulator

4) now open Terminal go till this Products path then type

lipo -create Debug-iphoneos/libTestStaticLibrary.a Debug-iphonesimulator/libTestStaticLibrary.a -output libTestStaticLibrary.a

5) Now open your project which uses this library, you need to drag and drop the static library files as well as the header files which have function declaration of static library functions.

6) Now, create Cocoa touch class file which will act as adaptor between static library and obejective -c files. Change the extension to .mm

MyCustomAdaptor.h

@interface MyCustomAdaptor : NSObject

-(int)getSub:(int ) a SecondParam:(int) b;

@end

MyCustomAdaptor.mm

#import "TestCPlusPlus.h"

@implementation MyCustomAdaptor

-(int)getSub:(int ) a SecondParam:(int) b
{
 int c = sub(a,b);
 return c;
}

@end

7) now use this MyCustomAdaptor in any of the objective c- file.

like image 74
vkhemnar Avatar answered Nov 09 '22 00:11

vkhemnar


Please notice that your .a is build with i386 or armv7? Generally, you should build both versions and combine them into one. like this: lipo -create -output libopencore-amrwb.a libopencore-amrwb-armv7.a libopencore-amrwb-i386.a

like image 31
LeverkusenFan Avatar answered Nov 08 '22 23:11

LeverkusenFan


I'm currently doing the same as you. I've had the same problem you describe here, actually the same two errors.

When you build your library you have to have in mind where're you going to use it, iOS device or simulator. This is important because you have to build for the different cases, this is very simple, when you build you library just check the "Select Scheme".

For Real device use:

enter image description here

Just to test in the simulator use:

enter image description here

After building just drag-drop the files created to the project you want to use the library and you're good to go!

like image 30
T.V. Avatar answered Nov 08 '22 23:11

T.V.