Objective-C:swift、objective-c、C++、C混合编程
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);
@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);
@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);
@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);
@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);
@import url(/css/cuteeditor.css);
1 Objective-C调用C++
在Object-C程序有两种文件.m和.mm文件。
- .m文件是Object-C文件,是完全兼容C语言,所以可以在.m文件中直接使用C语言的语法。
- .mm文件是Object-C++文件,是完全兼容C++和C语言,所以可以在.mm文件中直接使用C++和C语言的语法。
所以当需要在Object-C中调用C++时,可以将.m文件直接重命名为.mm文件,这样就可以使用C++的语法和内容了。
如在main.mm文件:
1 #import <Foundation/Foundation.h>
2 #import <iostream> //这里不是用include C++的头文件,而是使用import
3 int main(int argc, const char * argv[]) {
4 @autoreleasepool {
5 std::cout<<"hello CPP"<<std::endl; //完全是C++的语法
6 }
7 return 0;
8 }
2 Swift调用Objective-C
在Swift文件中要使用Object-C的内容,需要创建一个桥接头文件,通过桥接头文件实现Object-C语法到swift语法的转换,从而以swift的语法,在swift文件中调用Object-C的函数或类等内容。桥接头文件的命名规则是:<工程名>-swift.h。
若需要在Swift中调用Object-C可以按如下步骤操作:
- 新建Object-C格式的Cocoa Class文件,并在创建的过程中通过Xcode帮忙选择桥接头文件;
- 在桥接头文件中,import所需要使用Object-C的头文件;
- 在swift文件中,按Swift语法调用Object-C的内容。
如在swift环境中需要创建Object-C类的对象:
- 在Object-C类文件:testObjectC.h声明为:
@interface testObjectC : NSObject
-(NSString*)sayHello:(NSString*)greeting withName: (NSString*)name;
@end
- 在桥接头文件的内容为:
#import "testObjectC.h" //以Object-C的语法import相应的头文件,目前只需import一个文件
- 在swift文件的内容为 :
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var obj : testObjectC = testObjectC(); //仍按swift语法调用Object—C的构造函数
var hello = obj.sayHello("Good morning", withName:"Tony")
}
3 Swift调用C
在swift文件中调用C语言,与在swift文件中使用Object-C类似,同样只需在桥接头文件import相应的头文件即可。
3.1 简单实例
如下是在Swift环境中调用C语言的函数:
- 在C语言testC.h文件中的声明:
#include <stdio.h>
void printC(int a); //在C语言头文件的声明,在testC.c文件中还有实现。
- 在桥接头文件的内容
#import "testC.h" //还是以Object-C语法import所需要的C语言头文件
- 在swift环境中调用
printC(2); //直接以C语言的语法调用
3.2 类型转换
由于swift和C两种语言的数据类型定义不完全相同,特别是在C语言中有指针的类型,而在swift中切没有,为了能够在swift环境中调用C语言的API函数,所以Apple在swift环境中定义了一些数据类型,从而能够以C语言的类型一一对应。
3.2.1 基本类型
如表 1所示是Swift环境中C语言调用API函数的数据类型映射表,即若要调用C语言的API,则需要定义表中左边的类型。
表 1
|
Swift Type |
C Type |
|
CBool |
bool |
|
Cchar |
char, signed char |
|
CUnsignedChar |
unsigned char |
|
Cshort |
short |
|
CUnsignedShort |
unsigned short |
|
CInt |
int |
|
CUnsignedInt |
unsigned int |
|
CLong |
long |
|
CUnsignedLong |
unsigned long |
|
CLongLong |
long long |
|
CUnsignedLongLong |
unsigned long long |
|
CWideChar |
wchar_t |
|
CChar16 |
char16_t |
|
CChar32 |
char32_t |
|
CFloat |
float |
|
CDouble |
double |
3.2.2 指针类型
由于在swift中没有指针类型,而C语言中存在指针。所以为了调用带有指针类型的C语言API,定义了表 2中swift指针类型。其中表 2中的Type是表 1中左边swift的基本类型,并且其可以用于返回值、变量和参数之间的转换。
表 2
|
Swift Syntax |
C Syntax |
|
UnsafePointer<Type> |
const Type * |
|
UnsafeMutablePointer<Type> |
Type * |
|
nil |
NULL |
|
COpaquePointer |
T* (T表示非基本类型) |
在C语言中的指针需要手动进行申请空间和释放空间,同样在swift语言中也需要手动进行操作;同时在C语言中还可使用"*"取得指针所在定址,而在Swift中若需要进行赋值和取值,则需要取用相应的方法。
表 3
|
Swift Syntax |
C Syntax |
description |
|
static func alloc(num: Int) -> UnsafeMutablePointer<Memory> |
Void *malloc(int ) |
申请定址空间 |
|
func dealloc(num: Int) |
Void Free(void* ) |
释放地址空间 |
|
func initialize(newvalue: Memory) |
*p = value |
给指针所指的地址进行赋值 |
|
var memory: Memory { get nonmutating set } |
Value = *p |
取得地址上的值 |
|
&v |
&v |
取得变量的地址 |
比如在定义的C语言的函数对指针的值进行修改,通过在swift环境中取得指针的值:
- C语言函数:
void testPoint(int* a)
{
printf("%d\n",*a);
*a = 44;
}
- swift环境调用
1 override func viewDidLoad()
2 {
3 var sp:UnsafeMutablePointer<Int32> = UnsafeMutablePointer<Int32>.alloc(1);
4 sp.memory = 33;// 或者是:sp.initialize(33)
5 testPoint(sp);
6 print(sp.memory);
7 sp.dealloc(1);
8 }
9
10
11 输出:
12 33
13 44
3.2.3 字符串
由于C语言的字符串可以简单分为两种:const和非const,所以swift与C语言之间的对应关系如所示。
表 4
|
Swift Syntax |
C Syntax |
|
UnsafeMutablePointer<CChar> |
Char * |
|
UnsafePointer |
Const char* |
虽然swift与C语言之间存在字符串的对应关系,但还需考虑UnsafeMutablePointer<CChar>或UnsafePointer<CChar>类型与swift语言的String字符串之间的转换。
- StringàUnsafePointer<CChar>
要将swift语言的String字符串转换为C语言的UnsafePointer<CChar>或者是UnsafeMutablePointer<CChar>,需要Object-C的NSString作为转换中介。

图 1
- UnsafePointer<CChar>àString
要将C语言的Unsafe Pointer<CChar>转换为swift语言的String,就不需要Object-C作为中介的,直接调用String类型的fromCString()函数就可以直接转换为Unsafe Pointer<CChar>。

图 2
- C语言函数:
void testString(char *str)
{
printf("C:%s\n",str);
strcpy(str,"world");
}
- swift环境调用
1 override func viewDidLoad() {
2 //声明swift、Object-C和C三种语言的字符串进
3 var ss:String = "hello";
4 var os:NSString ;
5 var cs:UnsafeMutablePointer<CChar> = UnsafeMutablePointer<CChar>.alloc(1);
6 //将swift的字符串ss转换为object-C的字符串os,然后将object-C的字符串os转换为C语言的字符串cs
7 os = NSString.init(string:ss)
8 cs = UnsafeMutablePointer<CChar>(os.cStringUsingEncoding(1))
9 testString(cs); //调用C语言的函数
10 ss = String.fromCString(cs)!; //将C语言的字符串cs直接转换为将swift的字符串ss
11 print("swift:"+ss);
12 }
- 输出:
C:hello
swift:world
4 swift调用C++
目前无法直接调用,需要一些特别的技巧。若需要可以通过Object-C对C++进行包装,然后在swift中调用Object-C,既以swiftàObject-CàC++这样的顺序调用。
5 参考文献
- Apple:《Using swift with cocoa and Objective-C 》P174
- 书:《swift开发指南》P232;
- Apple:《Using Swift with Cocoa and Objective-C (Swift 2.1): Interacting with C APIs》
Objective-C:swift、objective-c、C++、C混合编程的更多相关文章
- Swift语言与Objective-C语言混合编程
首先创建一个Swift的Single View工程 然后直接在工程中新建OC文件: 然后选择OC语言之后会问你是否自动创建OC和Swift的中间文件: 然后工程文件夹里就有了三个文件: 现在OC头文件 ...
- IOS-Swift、Objective-C、C++混合编程
1.Objective-C调用C++代码 后缀为m文件的是Objective-C的执行文件,而后缀为mm文件的是Objective-C++文件. 直接在Objective-C中是无法调用C++代码的, ...
- Objective C & Swift & iOS & App
Objective C & Swift & iOS & App https://www.runoob.com/ios/ios-objective-c.html https:// ...
- swift 与 OC 混合编程
原文地址:http://www.cocoachina.com/swift/20150608/12025.html 一.解决问题 Swift项目需要使用封装好的Objective-c组件.第三方类库,苹 ...
- Swift 与 C 语言混合编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- Objective-C与Swift的混合编程
Swift 被设计用来无缝兼容 Cocoa 和 Objective-C .在 Swift 中,你可以使用 Objective-C 的 API(包括系统框架和你自定义的代码),你也可以在 Objecti ...
- Swift和Objective-C混合编程——Swift调用OC
在iOS应用的开发中.Swift必将代替OC,两者的趋势是"短期共存,长期代替".但曾经有太多的代码是用OC语言完毕的,而Swift的开发也从 OC中继承了非常多的特性.两者也是有 ...
- iOS自学-混合编程
OC调用swift,引入头文件 #improt "工程名字-swift.h" swift调用OC,在桥梁文件里面引入OC文件 的头文件 尽情混合编程吧...
- iOS- Swift和Object-C的混合编程
1.前言 事实证明,在短时间内Swift还取代不了Object-C, 而且.... Apple Swift 开发小组的人说的:「We'll recommend people start with ...
随机推荐
- C#与C++的几个不同之处知识点
1.索引器 索引器是C#自创的内容,这是C++当中没有的内容,所以做一次笔记. 索引器是用于书写一个可以通过使用[]想数组一样直接访问集合元素的方法.我们只需要指定待访问实例或元素的索引.索引器的语法 ...
- Java简单购物车设计
还是存在一些问题(比如clear函数没效果.乱码,单独测试也没,确实找不到问题),路过的给解决下... 第一部分 会话控制 会话跟踪: 使用隐藏表单字段 URL重写,实际就是直 ...
- html5自定义标签选择器
* E[attr]:只使用属性名,但没有确定任何属性值 * E[attr="value"]:指定属性名,并指定了该属性的属性值.必须和元素的属性完全匹配 * E[attr~=&qu ...
- C/C++ 中的0长数组(柔性数组)
转自C/C++ 中的0长数组(柔性数组) 在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的.但是,GUN中却允许使用,而且,很多时候,应用在了 ...
- 14.6.5 Configuring InnoDB Change Buffering 配置InnoDB Change Buffering
14.6.5 Configuring InnoDB Change Buffering 配置InnoDB Change Buffering 当插入,更新,和删除操作在表上执行, 索引列的值(特别是 se ...
- bzoj3143
之前我们曾经用dp解决过数学期望问题,这次我们用的是解方程的方法首先在编号之前,肯定要求出每条边的期望经过次数然后可以转化为求边端点的期望次数这种做法我一开始接触是noip2013的初赛问题求解,是类 ...
- 大脑提取每一个体素26领域的matlab代码
%-------------- outer loop for x= 1:40 for y =1:48 for z =1:34 %----------inter loop x=20; y=30; z=1 ...
- Spark使用CombineTextInputFormat缓解小文件过多导致Task数目过多的问题
目前平台使用Kafka + Flume的方式进行实时数据接入,Kafka中的数据由业务方负责写入,这些数据一部分由Spark Streaming进行流式计算:另一部分数据则经由Flume存储至HDFS ...
- UVA 11021 Tribles(递推+概率)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33059 [思路] 递推+概率. 设f[i]表示一只Tribble经 ...
- margin设置为负数
1.为负margin“平反” 我们在CSS中都会使用margin,但将margin设置成负数,那可能就不大好处理了.在网页设计中,人们对负margin用法的态度大相径庭,有的人非常喜欢,而有的人则认为 ...