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,
- Select your file.
- Open the File Info dialog (Cmd+I)
- 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.
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:
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:
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:
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.
If you add a
.swift
file to an older project and get the errordyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, try completely restarting Xcode.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 toNSObjectProtocol
(easiest way to do this is to inherit fromNSObject
), or to be anenum
marked@objc
with a raw value of some integer type likeInt
. 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.
- Create a new iOS project.
- Add a C file by click command+N. Select C file with header.
- 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.
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;
}Add C header to bridging file:
// ModuleName-Bridging-Header.h
#import "example.h"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:
Instead of bridging header you can use modulemap file. It's more flexible and convenient but a little harder to setup.
Related Topics
Why Is There No Transform_If in the C++ Standard Library
What Is Decltype with Two Arguments
Isn't the Const Modifier Here Unnecessary
What Is Going on with 'Gets(Stdin)' on the Site Coderbyte
Which Std::Async Implementations Use Thread Pools
Acquire/Release Semantics with Non-Temporal Stores on X64
C++ Template Friend Operator Overloading
What Is the Scope of a 'While' and 'For' Loop
Allocconsole() Not Displaying Cout
Memory Allocation Char* and Char[]
Compute Median of Values Stored in Vector - C++
Getline() Does Not Work If Used After Some Inputs
"Inline" Keyword VS "Inlining" Concept
Why Does Libc++'s Implementation of Std::String Take Up 3X Memory as Libstdc++
Cmake Unable to Determine Linker Language with C++