swift、object-c、C++、C混合编程

1 Object-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调用Object-C

在Swift文件中要使用Object-C的内容,需要创建一个桥接头文件,通过桥接头文件实现Object-C语法到swift语法的转换,从而以swift的语法,在swift文件中调用Object-C的函数或类等内容。桥接头文件的命名规则是:<工程名>-swift.h。

若需要在Swift中调用Object-C可以按如下步骤操作:

  1. 新建Object-C格式的Cocoa Class文件,并在创建的过程中通过Xcode帮忙选择桥接头文件;
  2. 在桥接头文件中,import所需要使用Object-C的头文件;
  3. 在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 参考文献

  1. Apple:《Using swift with cocoa and Objective-C 》P174
  2. 书:《swift开发指南》P232;
  3. Apple:《Using Swift with Cocoa and Objective-C (Swift 2.1): Interacting with C APIs》
  4. 在Swift中使用C语言的指针
  5. Swift的String与C语言中的字符串char*之间的转换
  6. 在Swift中使用历史遗留的C API
  7. 博客:swift调用C语言/C++函数的方法
  8. 网络视频:iOS-Swift、Objective-C、C++混合编程
时间: 2024-10-26 02:16:44

swift、object-c、C++、C混合编程的相关文章

Swift语言与Objective-C语言混合编程

首先创建一个Swift的Single View工程 然后直接在工程中新建OC文件: 然后选择OC语言之后会问你是否自动创建OC和Swift的中间文件: 然后工程文件夹里就有了三个文件: 现在OC头文件和实现文件中写好一个实例: 然后在Swift语言与Obje...ridging-Header.h文件中 然后就可以直接在swift语言中使用了:

Swift、OC、C++混合编程

OC调用C++: 1.创建oc工程: 2.主要步骤:将某个.m文件后缀改为.mm, 3.创建c++文件 #ifndef __Test__CPPHello__ #define __Test__CPPHello__ #include <stdio.h> class CPPHello { public: static void hello(); }; #endif /* defined(__Test__CPPHello__) */ CPPHello.h 1 void CPPHello::hello(

IOS-Swift、Objective-C、C++混合编程

1.Objective-C调用C++代码 后缀为m文件的是Objective-C的执行文件,而后缀为mm文件的是Objective-C++文件. 直接在Objective-C中是无法调用C++代码的,所以如果需要在Objective-C调用C++语言就需要直接将后缀m文件改为mm,然后就可以调用C++代码了. Objective-C兼容C,Objective-C++兼容C.C++. 接下来是在OC工程中创建C++文件,并调用C++的代码: 然后在OC文件中直接用C++的语法调用C++,所以前提是

在OC项目中添加Swift文件并实现混合编程

对于已经工作的开发者,并不适合也没有条件从一个全新的swift项目开始,进行开发. 虽然网上关于swift和oc混合编程的教程比较多,但是大多是基于 swift项目的,所以对咱们 OCer的参考价值有一定折扣. 现在swift虽然仍然存在很多缺陷,但是鉴于苹果的强势,是时候在项目中把简单的功能交给swift了,给自己,给项目,给swift一个缓冲区,都是极好的. 说了这么多,开始上代码. 现在的背景是: 已经有一个oc项目了,我想要加入 swfit,并且实现 oc调用 swift ,swift调

Swift和Objective-C混合编程——Swift调用OC

在iOS应用的开发中,Swift必将取代OC,两者的趋势是"短期共存,长期取代".但以前有太多的代码是用OC语言完成的,而Swift的开发也从 OC中继承了很多的特性,两者也是有很多的类似之处.目前Swift和OC可以实现无缝的混合编程. 我这里会实现一个简单的Swift调用OC的iOS实例,实现过程是十分的简单的.就像我们所有的Hello World一样.具体操作步骤如下: (1)Xcode中新建一个iOS项目,语言选择Swift,设备选择iPhone.目录结构如下: (2)然后在该

Swift和Objective-C混合编程——OC调用Swift

既然讲的是Swift和OC的混合编程,我的上一篇博客<Swift和Objective-C混合编程--Swift调用OC>讲的是如何在一个Swift项目中调用OC代码,现在我们要实现在OC项目中调用Swift代码,也是非常的方便.具体实现步骤如下: (1)创建一个iOS项目,语言选择OC,设备选择iPhone. (2)然后在项目中右键,New Files,选择Cocoa Touch Class,然后语言选择Swift.继承自NSObject.新建,会有一个对话框,选择Yes即可. . (3)此时

iOS混合编程之使用Swift+Objective-C调用WebService

最近由于项目的需要,要使用Swift语言开发个iOS项目,某个简单的需求就是要调用远程的WebService数据.问题出现了,网上有很多使用OC调用WebService的例子,但是几乎没有找到使用Swift调用WebService的例子,我苦苦搜索了好几个小时,就是没有满足我要求的,怎么办,项目要泡汤了?Swift和OC,我该怎么选择? 天无绝人之路,还好Swift和OC可以完美的实现混合编程,可以相互实现调用.然后又在网上找到一个使用OC访问WebService的例子http://my.osc

Qt Quick 之 QML 与 C++ 混合编程详解

Qt Quick 技术的引入,使得你能够快速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ,多线程,又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等,在 QML 中要么不可用,要么用起来不方便,所以呢,很多时候我们是会基于这样的原则来混合使用 QML 和 C++: QML 构建界面, C++ 实现非界面的业务逻辑和复杂运算. 请给

QML与C++混合编程详解

1.QML与C++为什么要混合编程 QML与C++为什么要混合编程,简单来说,就是使用QML高效便捷地构建UI,而C++则用来实现业务逻辑和复杂算法,下面介绍了两者间交互的方法与技巧. 2.QML访问C++概述 Qt集成了QML引擎和Qt元对象系统,使得QML很容易从C++中得到扩展,在一定的条件下,QML就可以访问QObject派生类的成员,例如信号.槽函数.枚举类型.属性.成员函数等. QML访问C++有两个方法:一是在Qt元对象系统中注册C++类,在QML中实例化.访问.二是在C++中实例