How to Use C++ with Objective-C in Xcode

How can I use C++ with Objective-C in XCode

Make sure you compile that file as "Objective-C++".

The simplest way is to rename it as *.mm.

If you don't want to rename the *.m file,

  1. Select your file.
  2. Open the File Info dialog (Cmd+I)
  3. In File Type, select "sourcecode.cpp.objcpp"

How to call C function from Objective-C

Objective-C is a superset of C. All you need to do is call it from your Objective-C code.

 char* args[] = { "foo", "bar", NULL }; // Might need the NULL to emulate command line arguments.
int result = mainFunction(2, args);

You could pass argc and argv directly from your own main

 int main(int argc, char** argv)
{
int result = mainFunction(argc, argv);
}

If your arguments are in an array of NSStrings, you'll need to convert them to a normal C array of C strings:

char** cStringArray = malloc(([stringArray count] + 1) * sizeof(char*));
for (int i = 0 ; i < [stringArray count] ; ++i)
{
NSString* aString = [stringArray objectAtIndex: i];
cStringArray[i] = [aString UTF8String];
}
cStringArray[[stringArray count]] = NULL;
int result = mainFunction([stringArray count], cStringArray);
free(cStringArray);

It's a long time since I last did any Objective-C, so apologies for any syntax errors.

How to use C, C++ program or classes in objective C (Xcode)?

Look in the folder "Supporting Files" for the file called main.m.

Rename it to main.mm

Now main is a c++ main.

Sample Image

How do I call Objective-C code from Swift?

Using Objective-C Classes in Swift

If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit #import <Foundation/Foundation.h to an older Objective-C File.)

Step 1: Add Objective-C Implementation -- .m

Add a .m file to your class, and name it CustomObject.m.

Step 2: Add Bridging Header

When adding your .m file, you'll likely be hit with a prompt that looks like this:

A macOS sheet-style dialog from Xcode asking if you would "like to configure an Objective-C bridging header"

Click Yes!

If you did not see the prompt, or accidentally deleted your bridging header, add a new .h file to your project and name it <#YourProjectName#>-Bridging-Header.h.

In some situations, particularly when working with Objective-C frameworks, you don't add an Objective-C class explicitly and Xcode can't find the linker. In this case, create your .h file named as mentioned above, then make sure you link its path in your target's project settings like so:

An animation demonstrating the above paragraph

Note:

It's best practice to link your project using the $(SRCROOT) macro so that if you move your project, or work on it with others using a remote repository, it will still work. $(SRCROOT) can be thought of as the directory that contains your .xcodeproj file. It might look like this:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Step 3: Add Objective-C Header -- .h

Add another .h file and name it CustomObject.h.

Step 4: Build your Objective-C Class

In CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

In CustomObject.m

#import "CustomObject.h"

@implementation CustomObject

- (void) someMethod {
NSLog(@"SomeMethod Ran");
}

@end

Step 5: Add Class to Bridging-Header

In YourProject-Bridging-Header.h:

#import "CustomObject.h"

Step 6: Use your Object

In SomeSwiftFile.swift:

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

There is no need to import explicitly; that's what the bridging header is for.

Using Swift Classes in Objective-C

Step 1: Create New Swift Class

Add a .swift file to your project, and name it MySwiftObject.swift.

In MySwiftObject.swift:

import Foundation

@objc(MySwiftObject)
class MySwiftObject : NSObject {

@objc
var someProperty: AnyObject = "Some Initializer Val" as NSString

init() {}

@objc
func someFunction(someArg: Any) -> NSString {
return "You sent me \(someArg)"
}
}

Step 2: Import Swift Files to ObjC Class

In SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

The file:<#YourProjectName#>-Swift.h should already be created automatically in your project, even if you can not see it.

Step 3: Use your class

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];

NSLog(@"RetString: %@", retString);

Notes:

  1. If Code Completion isn't behaving as you expect, try running a quick build with R to help Xcode find some of the Objective-C code from a Swift context and vice versa.

  2. If you add a .swift file to an older project and get the error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, try completely restarting Xcode.

  3. While it was originally possible to use pure Swift classes (Not descendents of NSObject) which are visible to Objective-C by using the @objc prefix, this is no longer possible. Now, to be visible in Objective-C, the Swift object must either be a class conforming to NSObjectProtocol (easiest way to do this is to inherit from NSObject), or to be an enum marked @objc with a raw value of some integer type like Int. You may view the edit history for an example of Swift 1.x code using @objc without these restrictions.

How to include C file in iOS project

You need to add Header file (like WOC_Random.h) in which you will declare the function

int randomInt(int startInt, int endInt);

Then define that function in WOC_Random.c. And then include WOC_Random.h in the class you want to use the function.

How to use c++ and objective-c together in XCode 4.2

Calling C++ code from Objective-C code involves ending your file with
.mm (instead of .m) so that the Objective-C++ compiler will be used.

This compiler can understand both C++ and Objective-C.

In other words, the ObjC++ compiler lets you put C++ code directly in
Objective-C methods, and vice versa.

Take a look at Cocoa_With_Carbon_or_CPP example and Strategies for Using C++ in Objective-C Projects (and vice versa) article .

Mixing C functions in an Objective-C class

Mixing C and Objective-C methods and function is possible, here is a simple example that uses the SQLite API within an iPhone App: (course site)

Download the Zip file (09_MySQLiteTableView.zip)

C functions need to be declared outside of the @implementation in an Objective-C (.m) file.

int MyCFunction(int num, void *data)
{
//code here...
}

@implementation

- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
//code here
}

@end

Because the C function is outside of the @implementation it cannot call methods like

[self doSomething]

and has no access to ivars.

This can be worked around as long as the call-back function takes a userInfo or context type parameter, normally of type void*. This can be used to send any Objective-C object to the C function.

As in the sample code, this can be manipulated with normal Objective-C operations.

In addition please read this answer: Mixing C functions in an Objective-C class

Call objective-c method from C library

You can absolutely call Objective-C methods from C functions. To do so, however, you will need to make sure that your C function has a reference to an Objective-C object of some kind. Your example above doesn't show that.

So, you might write your function as:

int doStuff(id ref, char* aString) {
[ref objcMethod];
....
return 0;
}

Or maybe you would store the ref in static storage in your library, so that it was available to all functions, without passing it explicitly. It really depends on your use-case. Remember that Classes are objects, too, in Objective-C; so if you need ref to be a class (for a static methods), that can work, too.

There is a tangential topic. Sometimes, in Objective-C you want a direct reference to a method implementation so that you can invoke it directly. This is handy in tight loops, where performance is required. If this is your need, this blog post goes into the topic.

How to build and use C library in iOS project?

Xcode can compile a C code without additional settings. Just add your C files to project and select proper target.

To use C code at Swift you should create bridging header.

Here is an example how to use C and Swift in same project from a scratch. You can do the same with your exist C code.

  1. Create a new iOS project.
  2. Add a C file by click command+N. Select C file with header.
    C file
  3. Xcode should suggest to add bridging header and create it automatically. If it doesn't happen you can do it manually by create header file and add it name to build settings of the project.
    Bridging header
    Build settings
  4. Add some function at C file. For example:

     // example.h
    #include <stdio.h>
    int exampleMax(int num1, int num2);

    // example.c
    #include "example.h"

    int exampleMax(int num1, int num2)
    {
    int result;
    if (num1 > num2)
    result = num1;
    else
    result = num2;
    return result;
    }
  5. Add C header to bridging file:

     // ModuleName-Bridging-Header.h
    #import "example.h"
  6. Now you can use C code at Swift files:

     import UIKit

    class ViewController: UIViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    let number1 = Int32(1)
    let number2 = Int32(5)
    let result = exampleMax(number1, number2)
    print("min = \(result)")
    }
    }

Auto completion should see your C header:

Auto completion

Instead of bridging header you can use modulemap file. It's more flexible and convenient but a little harder to setup.



Related Topics



Leave a reply



Submit