转自:http://www.xue5.com/Mobile/iOS/661674.html

如何将C++和Object-C混合编程开发IOS软件(Object-c调用C++)

原文网址:http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/o*****lusPlus.html

Using C++ With Objective-C
苹果的Objective-C编译器允许用户在同一个源文件里自由地混合使用C++和Objective-C,混编后的语言叫Objective-C++。有了它,你就可以在Objective-C应用程序中使用已有的C++类库。

Objective-C和C++混编的要点
在Objective-C++中,可以用C++代码调用方法也可以从Objective-C调用方法。在这两种语言里对象都是指针,可以在任何地方使用。例如,C++类可以使用Objective-C对象的指针作为数据成员,Objective-C类也可以有C++对象指针做实例变量。下例说明了这一点。
注意:Xcode需要源文件以".mm"为扩展名,这样才能启动编译器的Objective-C++扩展。

复制代码
  1. /* Hello.mm
  2. * Compile with: g++ -x objective-c++ -framework Foundation Hello.mm -o hello
  3. */
  4. #import <Foundation/Foundation.h>
  5. class Hello {
  6. private:
  7. id greeting_text; // holds an NSString
  8. public:
  9. Hello() {
  10. greeting_text = @"Hello, world!";
  11. }
  12. Hello(const char* initial_greeting_text) {
  13. greeting_text = [[NSString alloc] initWithUTF8String:initial_greeting_text];
  14. }
  15. void say_hello() {
  16. printf("%s\n", [greeting_text UTF8String]);
  17. }
  18. };
  19. @interface Greeting : NSObject {
  20. @private
  21. Hello *hello;
  22. }
  23. - (id)init;
  24. - (void)dealloc;
  25. - (void)sayGreeting;
  26. - (void)sayGreeting:(Hello*)greeting;
  27. @end
  28. @implementation Greeting
  29. - (id)init {
  30. if (self = [super init]) {
  31. hello = new Hello();
  32. }
  33. return self;
  34. }
  35. - (void)dealloc {
  36. delete hello;
  37. [super dealloc];
  38. }
  39. - (void)sayGreeting {
  40. hello->say_hello();
  41. }
  42. - (void)sayGreeting:(Hello*)greeting {
  43. greeting->say_hello();
  44. }
  45. @end
  46. int main() {
  47. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  48. Greeting *greeting = [[Greeting alloc] init];
  49. [greeting sayGreeting]; // > Hello, world!
  50. Hello *hello = new Hello("Bonjour, monde!");
  51. [greeting sayGreeting:hello]; // > Bonjour, monde!
  52. delete hello;
  53. [greeting release];
  54. [pool release];
  55. return 0;
  56. }

正如你可以在OC接口中声明C结构一样,你也可以在OC接口中声明C++类。跟C结构一样,OC接口中定义的C++类是全局范围的,不是OC类的内嵌类(这与标准C(尽管不是C++)提升嵌套结构定义为文件范围是一致的)。
为了允许你基于语言变种条件化地编写代码,OC++编译器定义了__cplusplus和__OBJC__预处理器常量,分别指定C++和OC。 如前所述,OC++不允许C++类继承自OC对象,也不允许OC类继承自C++对象。

复制代码
  1. class Base { /* ... */ };
  2. @interface ObjCClass: Base ... @end // ERROR!
  3. class Derived: public ObjCClass ... // ERROR!

与OC不同的是,C++对象是静态类型的,有运行时多态是特殊情况。两种语言的对象模型因此不能直接兼容。更根本的,OC和C++对象在内存中的布局是互不相容的,也就是说,一般不可能创建一个对象实例从两种语言的角度来看都是有效的。因此,两种类型层次结构不能被混合。
你可以在OC类内部声明C++类,编译器把这些类当作已声明在全局名称空间来对待。就像下面:

复制代码
  1. @interface Foo {
  2. class Bar { ... } // OK
  3. }
  4. @end
  5. Bar *barPtr; // OK

OC允许C结构作为实例变量,不管它是否声明在OC声明内部。

复制代码
  1. @interface Foo {
  2. struct CStruct { ... };
  3. struct CStruct bigIvar; // OK
  4. } ... @end

Mac OS X 10.4以后,如果你设置fobjc-call-cxx-cdtors编译器标志,你就可以使用包含虚函数和有意义的用户自定义零参数构造函数、析构函数的C++类实例来做为实例变量(gcc-4.2默认设置编译器标志fobjc-call-cpp-cdtors)。OC成员变量alloc完以后,alloc函数会按声明顺序调用构造器。构造器使用公共无参数恰当的构造函数。OC成员变量dealloc之前,dealloc方法按声明顺序反序调用调用析构函数。 OC没有名称空间得概念。不能在C++名称空间内部声明OC类,也不能在OC类里声明名称空间。
OC类,协议,分类不能声明在C++ template里,C++ template也不能声明在OC接口,协议,分类的范围内。
但是,OC类可以做C++ template的参数,C++ template参数也可以做OC消息表达式的接收者或参数(不能通过selector)。

C++词汇歧义和冲突
OC头文件中定义了一些标识符,所有的OC程序必须包含的,这些标识符识id,Class,SEL,IMP和BOOL。
OC方法内,编译器预声明了标识符self和super,就想C++中的关键字this。跟C++的this不同的是,self和super是上下文相关的;OC方法外他们还可以用于普通标识符。
协议内方法的参数列表,有5个上下文相关的关键字(oneway,in,out,inout,bycopy)。这些在其他内容中不是关键字。
从OC程序员的角度来看,C++增加了不少新的关键字。你仍然可以使用C++的关键字做OC selector的一部分,所以影响并不严重,但你不能使用他们命名OC类和实例变量。例如,尽管class是C++的关键字,但是你仍然能够使用NSObject的方法class:

复制代码
  1. [foo class]; // OK

然而,因为它是一个关键字,你不能用class做变量名称:

复制代码
  1. NSObject *class; // Error

OC里类名和分类名有单独的命名空间。@interface foo和@interface(foo)能够同时存在在一个源代码中。OC++里,你也能用C++中的类名或结构名来命名你的分类。
协议和template标识符使用语法相同但目的不同:

复制代码
  1. id<someProtocolName> foo;
  2. TemplateType<SomeTypeName> bar;

为了避免这种含糊之处,编译器不允许把id做template名称。 最后,C++有一个语法歧义,当一个label后面跟了一个表达式表示一个全局名称时,就像下面:

复制代码
  1. label: ::global_name = 3;

第一个冒号后面需要空格。OC++有类似情况,也需要一个空格:

复制代码
  1. receiver selector: ::global_c++_name;

限制
OC++没有为OC类增加C++的功能,也没有为C++类增加OC的功能。例如,你不能用OC语法调用C++对象,也不能为OC对象增加构造函数和析构函数,也不能将this和self互相替换使用。类的体系结构是独立的。C++类不能继承OC类,OC类也不能继承C++类。另外,多语言异常处理是不支持的。也就是说,一个OC抛出的异常不能被C++代码捕获,反过来C++代码抛出的异常不能被OC代码捕获。

Object-C与标准C/C++混合编程的更多相关文章

  1. C# 托管和非托管混合编程

    在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难.   最直接的实现托管与非托管编程的方法就是 ...

  2. 使用 ctypes 进行 Python 和 C 的混合编程

    Python 和 C 的混合编程工具有很多,这里介绍 Python 标准库自带的 ctypes 模块的使用方法. 初识 Python 的 ctypes 要使用 C 函数,需要先将 C 编译成动态链接库 ...

  3. Java语言与C语言混合编程(2)--在Java中调用C语言本地库

    在上一篇文章中介绍了Java语言中的native关键字,以及Java语言调用C语言的编译生成本地动态链接库(DLL)实现加法运算的小例子,本文通过一个更加详细的例子,深入讲解Java语言调用C语言的函 ...

  4. 如玫瑰一般的PHP与C#混合编程

    故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...

  5. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  6. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  7. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  8. C#与MATLAB混合编程

    C#和MatLab的混合编程,充分利用了winform的直观显示和matlab的强大计算能力.在此以一个小例子的形式给大家讲述一下二者混合编程的实现. 一.软件的配置说明 C#版本:VS2010 ma ...

  9. matlab封装DLL混合编程总结

    最近做了个项目要用到matlab做些算法处理,然后用.net项目调用这个类,我把这个matlab封装dll总结了下如下: matlab是商业数学软件,优势是在算法开发上面有很强的功能,提供了很多数学算 ...

随机推荐

  1. 02-C#笔记-类的定义

    /* * Notes: * 1. 标识符必须以字母.下划线或 @ 开头,后面可以跟一系列的字母.数字( 0 - 9 ).下划线( _ ).@ * */ using System; namespace ...

  2. django -- 安装django

    安装 通过cmd进行安装 pip3 install django==1.11.11 创建django项目 通过命令行进行创建 下面的命令创建了一个名为"mydjango"的Djan ...

  3. 从零和使用mxnet实现线性回归

    1.线性回归从零实现 from mxnet import ndarray as nd import matplotlib.pyplot as plt import numpy as np import ...

  4. 用luks方式对磁盘进行加密以及加密磁盘的自动挂载

    1.关于luks加密 LUKS(Linux Unified Key Setup)为Linux硬盘分区加密提供了一种标准,它不仅能通用于不同的 Linux发行版本,还支持多用户/口令.因为它的加密密钥独 ...

  5. Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理

    本文非常详尽地介绍了Java中的三个集合类 ArrayList,Vector与Stack <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整 ...

  6. 亿级Web系统搭建 Web负载均衡的几种实现方式(阿里)

    我还写了两篇详细的 参考:六大Web负载均衡原理与实现 参考:LVS(Linus Virtual Server):三种IP负载均衡方式比较+另三种Web负载均衡方式 其中LVS.HAProxy可以工作 ...

  7. cad.net 获取所有已经安装的cad版本信息

    计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\Hardcopy var ackey = Registry.LocalMachine.OpenSubKey(@&quo ...

  8. Maven设置MAVEN_OPTS环境变量

    原文地址:https://blog.csdn.net/porsche_gt3rs/article/details/78787491 一 原因: 运行mvn命令实际是执行java命令,既然是运行java ...

  9. 快速排序详解(C语言/python)

    快速排序详解 介绍: 快速排序于C. A. R. Hoare在1960年提出,是针对冒泡排序的一种改进.它每一次将需要排序的部分划分为俩个独立的部分,其中一个部分的数比的数都小.然后再按照这个方法对这 ...

  10. Mysql 学习参考

    [1]Mysql 基础知识 (1)<Mysql 官网> (2)<菜鸟教程之Mysql数据库教程> (3)<C语言中文网之Mysql数据库栏> (4)<W3Sc ...