How do I include cross-platform c++ code in my XCode app

I am trying to create a cross platform application where some of the code is shared among the Android and iOS version and is written in c++ however I am not really sure where to begin with the XCode/iOS/Swift side of things. I can write c++ code but I am not sure where to put it. Most of the tutorials I can find show how to include already compiled c++ code into your project but I want to be able to write it alongside my swift code just like I might do with a bridging header in objective-c.


How can I set up XCode so I can edit and compile my c++ code alongside my Swift code?

Replies

Hello Caleb K,

Just put the source files in your project and they will be compiled. Getting them to work with Swift will be the challenge. It can be done and isn't that hard, but it is tedious.

Could you elaborate a bit more on what exacly will be the challenge of it?

For my application all that needs to happen:
A. An update function called with a bunch of numerical parameters and acouple structs passed from the swift code to the c++ code

B. An array of structs back to the swift code to use for geometry to be rendered

It is not a challenge really, just tedious. Swift is not compatible with C++. You must either expose your C++ via a C interface or via an Objective-C interface. My recommendation would be an Objective-C wrapper. That will enable you to keep all of the tedium and complexities contained within the wrapper code. You Swift code will be cleaner as a result.

What do I call the file names if there is c++ code? isnt objective-c already using the ".h" extension? Generally when I write my c++ code the header is in a ".h" file and the implementation is in a ".cpp" file how will the compiler know which files to complile as c++ code?

Header files are the same on any platform. They are just .h files. The language used when parsing them is based on the language of the implementation file that includes them. Modern C++ can be heavily template-based with most of the code in the header files. You have to make sure that neither Swift nor Objective-C ever sees any of that C++ code.


Yyou can write Objective-C++ wrapper classes that can understand the C++ and re-publish it as Swift-compatible Objective-C. Each Objective-C++ class will need two header files. One header file exposes Objective-C methods only. The other header is a private Objective-C++ header that holds pointers to any native C++ objects.

Would you be willing to make an example of this in code of say just a simple function that adds two numbers together? This is really new to me.

I'll try, but it has been a long time since I've written C++.



C++ Adder.h

class Adder
  {
  int add(int a, int b);
  };
 
int Adder::add(int a, int b)
  {
  return a + b;
  }
 
Objective-C++ PrefixAdder.h

@interface PrefixAdder

- (int) addA: (int) a B: (int) b;

@end

Objective-C++ PrefixAdder++.h

@interface PrefixAdder ()

@property (assign) Adder * adder;

@end

Objective-C++ PrefixAdder.mm

#import "PrefixAdder.h"
#import "PrefixAdder++.h"

@implementation PrefixAdder

@synthesize adder = myAdder;

- (instancetype) init
  {
  myAdder = new Adder();
 
  if(myAdder != NULL)
    self = [super init];
   
  return self;
  }
 
- (void) dealloc
  {
  delete myAdder;
  myAdder = 0;
 
  [super dealloc]; 
  }
 
- (int) addA: (int) a B: (int) b
  {
  if(self.adder)
    return self.adder->add(a, b);
   
  return 0;
  }
 
@end


You might want to comment out the "[super dealloc]" if using ARC. I suggest keeping ARC off since it isn't going to help you with the C++ anyway. May as well stay focused on memory.


Obviously, this is only worth the effort if you have a C++ library so wonderful that you couldn't ever attempt to re-do it. In my case, GDAL totally qualifies.


You should be able to import the "Prefix" framework as-is into Swift. You may have to do something funky with header module names in case those conflict. In my case, there is already a "gdal.h" in GDAL, so the default "GDAL.h" framework header that Xcode wants to make won't work. I hack that to be something else.

Thank you. I really appreciate the help.

Caleb K,


Did you ever get this to work the way john daniel prescribed?

Have you ever succeeded in getting code to work this way, or is this a theory only?

It works fine. I haven't shipped anything with it because I've been busy with other projects. Once you get something, in any language, to build as a framework, you can use that framework in Swift.

Hi sir,


can you by chance help me out a little more with getting GDAL to work on IOS?

I have completed all steps in the following link:

https://stackoverflow.com/questions/12643898/incorporating-gdal-ogr-into-an-ios-project-a-quick-guide

using the following shell:

https://gist.github.com/lachlanhurst/745e1e1d196c3e697450

but have no clue how to implement it into swift. Id like to tile some kap files but would find it very helpful if you could help me call something simple like gdalinfo on a file if you have a moment.


cheers,

You have asked a number of related, but not identical questions.


If you just want to get GDAL working on iOS, your best bet would be to stick to Objective-C++ and then you can integrate with GDAL with no issues. Getting GDAL built can be a challenge. Don't forget that some GDAL modules, most importantly GEOS and Spatialite are GPL and legally incompatible with the App Store.


If you really, really want to get it working with Swift, I do have some scripts that use the doxygen XML output to build Objective-C++ wrappers that would, eventually, be Swift compatible. However, this project is currently on hiatus due to an unexpected bout of sanity.


If you just want to run gdalinfo on your Mac, you can do that easy enough. You may be able to install GDAL via homebrew or something.


I recently updated my own GDAL build scripts (at https://github.com/etresoft/OS-GIS). Both of those examples you referenced no longer work. The second one even uses a really ancient version of GDAL too. The version I have is almost up-to-date. It runs with about 99% successful test coverage on Linux and macOS. The scripts are designed to build for iOS too, but I haven't tried that in a couple of years.

Sorry for the duplicate post. Every time I see someone post links I think Apple must have rescinded it nebulous moderation policy. And then I wind up having to make duplicate posts. I have no idea when you originally made your post. Nor do I have any idea when my reply will surface from moderation purgatory. Here is a hacked version:


You have asked a number of related, but not identical questions.


If you just want to get GDAL working on iOS, your best bet would be to stick to Objective-C++ and then you can integrate with GDAL with no issues. Getting GDAL built can be a challenge. Don't forget that some GDAL modules, most importantly GEOS and Spatialite are GPL and legally incompatible with the App Store.


If you really, really want to get it working with Swift, I do have some scripts that use the doxygen XML output to build Objective-C++ wrappers that would, eventually, be Swift compatible. However, this project is currently on hiatus due to an unexpected bout of sanity.


If you just want to run gdalinfo on your Mac, you can do that easy enough. You may be able to install GDAL via homebrew or something.


I recently updated my own GDAL build scripts (at [REDACTED] - try github.com/etresoft/OS-GIS ). Both of those examples you referenced no longer work. The second one even uses a really ancient version of GDAL too. The version I have is almost up-to-date. It runs with about 99% successful test coverage on Linux and macOS. The scripts are designed to build for iOS too, but I haven't tried that in a couple of years.

Hi @john daniel,

I've building an app which require to integrate GDAL, Your link provided to GitHub is also expired. Any help to do the same will be really appreciated.

Thanks in advance. Cheers