先说题外话,文章标题其实起的不好,在iOS的开发中,Apple建立的库基本都是用Objective-C写的,所以在这里的C++指的其实是Objective-C++。

首先,最最最要紧的事情,不是代码而是编译器选项,在做混合编译之前一定要把编译器的Compile Sources As选项改为Objective C++。

默认的选项是According to file type,用这个的话,你后面每个不在交叉行列里的类都OK,一旦两种语言在一个文件中相互调用,就会报错,而且报的错怪的很,比如:找不到new,找不到delete,等等。


既然是调用嘛,肯定要有来有往,先说说,在C++中如何调用Objective-C:(参考这个,我略做修改) 

1. 封装Objective-C的对象函数变为C的函数接口


2. 写一个对应的C++类调用

说起来简单,看看例子就知道什么情况了。



// 
  MyObject-C-Interface.h 
  
 
  
 #ifndef __MYOBJECT_C_INTERFACE_H__
 
  #define 
  __MYOBJECT_C_INTERFACE_H__ 1 
  

 
  int 
  MyObjectDoSomethingWith ( 
  void 
   
  * 
  myObjectInstance,  
  void 
   
  * 
  parameter);

 
  #endif 
  

 
  // 
  MyObject.h 
  
 
  
 #import  
  " 
  MyObject-C-Interface.h 
  " 
  

 @interface MyObject : NSObject
 {
      
  int 
  someVar;
 }

 
  - 
  ( 
  int 
  ) doSomethingWith:( 
  void 
   
  * 
  ) aParameter;
 @end

 
  // 
  MyObject.m 
  
 
  
 #import  
  " 
  MyObject.h 
  " 
  

 
  int 
  MyObjectDoSomethingWith ( 
  void 
   
  * 
  self,  
  void 
   
  * 
  aParameter)
 {
      
  return 
  [(id) self doSomethingWith:aParameter];
 }

 @implementation MyObject

 
  - 
  ( 
  int 
  ) doSomethingWith:( 
  void 
   
  * 
  ) aParameter
 {
      
  // 
  ... some code 
  
 
      
  return 
   
  1 
  ;
 }

 @end

 
  // 
  MyCPPClass.h 
  
 
  #ifndef __MYCPPCLASS_H__
 
  #define 
  __MYCPPCLASS_H__ 
  

 
  class 
  MyCppClass
 {
 
  public 
  :
       
  int 
  MyCPPClass::someMethod ( 
  void 
   
  * 
  objectiveCObject,  
  void 
   
  * 
  aParameter);
 }

 
  #endif 
  

 
  // 
  MyCPPClass.cpp 
  
 
  
 #include  
  " 
  MyCPPClass.h 
  " 
  
 #include  
  " 
  MyObject-C-Interface.h 
  " 
  

 
  int 
  MyCPPClass::someMethod ( 
  void 
   
  * 
  objectiveCObject,  
  void 
   
  * 
  aParameter)
 {
      
  return 
  MyObjectDoSomethingWith (objectiveCObject, aParameter);
 }


如上面所示,先搞个弱类型的C函数接口,然后在Objective C的类中实现该接口。最后,在C++的类中调用弱类型,和弱接口。


在工程主体框架是用Objective-C写成的前提下,上面的这种调用并不实用,完全是技术可能性的研究。说白了,就是骗骗编译器玩,同时也失去了C++优雅的强类型特性。


下面这个才是真金白银有用的,在Objective-C代码下调用C++类代码:

1. 建立一个C++类

2. 写一个Adaptor的Objective-C类

3. 在其他Objective-C的逻辑中调用Adaptor类。

还是代码:)


// 
  
 
  // 
   CPlusPlusClass.h
 
  // 
   MixCompileTest
 
  // 
  
 
  // 
   Created by biosli on 11-4-30.
 
  // 
   Copyright 2011 __MyCompanyName__. All rights reserved.
 
  //
 
  
 #ifndef __CPLUSPLUS_CLASS_H__
 
  #define 
  __CPLUSPLUS_CLASS_H__ 
  

 
  class 
  CPlusPlusClass {
 
  public 
  :
     CPlusPlusClass();
      
  virtual 
   
  ~ 
  CPlusPlusClass();
      
  void 
  func();
      
  void 
  setInt ( 
  int 
  i) {
         m_i  
  = 
  i;
     }
     
 
  private 
  :
      
  int 
  m_i;
 };


 
  #endif 
  

 
  // 
  
 
  // 
   CPlusPlusClass.mm
 
  // 
   MixCompileTest
 
  // 
  
 
  // 
   Created by biosli on 11-4-30.
 
  // 
   Copyright 2011 __MyCompanyName__. All rights reserved.
 
  //
 
  
 #include  
  < 
  stdio.h 
  > 
  
 #include  
  " 
  CPlusPlusClass.h 
  " 
  

 CPlusPlusClass::CPlusPlusClass() : m_i( 
  0 
  ) 
 {
     printf( 
  " 
  CPlusPlusClass::CPlusPlusClass()\n 
  " 
  );
     func();
 }

 CPlusPlusClass:: 
  ~ 
  CPlusPlusClass() 
 {
     printf( 
  " 
  CPlusPlusClass::~CPlusPlusClass()\n 
  " 
  );
 }

 
  void 
  CPlusPlusClass::func() {
     printf( 
  " 
  CPlusPlusClass func print: %d\n 
  " 
  , m_i);
 }

 
  // 
  
 
  // 
   ObjectiveCAdaptor.h
 
  // 
   MixCompileTest
 
  // 
  
 
  // 
   Created by biosli on 11-4-30.
 
  // 
   Copyright 2011 __MyCompanyName__. All rights reserved.
 
  //
 
  
 #import  
  < 
  Foundation 
  / 
  Foundation.h 
  > 
  

 
  class 
  CPlusPlusClass;  
  // 
  这个声明得小心,千万不要写成@class,兄弟我搞了半宿才找到这个错误。呵呵,见笑,见笑。 
  
 
  
 @interface ObjectiveCAdaptor : NSObject {
 @private
     CPlusPlusClass  
  * 
  testObj;
 }

 
  - 
  ( 
  void 
  ) objectiveFunc;
 @end

 
  // 
  
 
  // 
   ObjectiveCAdaptor.m
 
  // 
   MixCompileTest
 
  // 
  
 
  // 
   Created by biosli on 11-4-30.
 
  // 
   Copyright 2011 __MyCompanyName__. All rights reserved.
 
  //
 
  
 #import  
  " 
  ObjectiveCAdaptor.h 
  " 
  
 #include  
  " 
  CPlusPlusClass.h 
  " 
  

 @implementation ObjectiveCAdaptor

 
  - 
  (id) init {
      
  if 
  (self  
  = 
  [super init]) {
         testObj  
  = 
   
  new 
  CPlusPlusClass();
     }
     
      
  return 
  self;
 }

 
  - 
  ( 
  void 
  ) dealloc {
      
  if 
  (testObj  
  != 
  NULL) {
         delete testObj;
         testObj  
  = 
  NULL;
     }
     [super dealloc];
 }

 
  - 
  ( 
  void 
  ) objectiveFunc
 {
     testObj 
  -> 
  setInt( 
  5 
  );
     testObj 
  -> 
  func();

 @end

 
  // 
  调用示例: 
  
 
  - 
  ( 
  void 
  ) callObjectiveCAdaptorMethod
 {
     ObjectiveCAdaptor  
  * 
  testObjectiveCObj  
  = 
  [[ObjectiveCAdaptor alloc] init];
     [testObjectiveCObj objectiveFunc];
     [testObjectiveCObj release];
 }



obj-c 的文件有 .h 和 .m



     










假设:



  1 我们的项目要使用  



  2 我们的项目中使用   C++库(在 xcode 中添加.a 静态库,静态库中封装 C++ 写的逻辑),  那么我们只需要添加静态库 以及加入 C++ 库中的头文件 ,然后直接调用 C++ 库中头文件声明的方法(还须修改一下编译环境 compile source as   的值为 objective-c ++ ,默认的是According to file type).



  3   我们的项目中使用 C库 和 C++ 库 ,   那么 要在 2 的基础之上 ,再他 所有的.c /.cpp 文件 改为 .mm 文件。 这样才能通过编译。





综上所述:



  如果 使用 C 静态库能满足 我们的所有需求,就不要使用 C++ 库,并且尽量避免三者混编。因为代价很大,要修改所有的 实现文件为 .mm 文件。