歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

關於C++和Objective-C混編

Objective-C在大部分情況下足夠滿足我們的需求,但是還是會有一些情況必須要使用C++,比如:

  1. 使用C++的庫
  2. 當Objective-C不夠快的時候

第一點自然不必多說,至於第二點,Objective-C的消息機制比起函數調用還是比較慢的,當對性能有極高要求的時候,就需要C/C++來替代。

C++與Objective-C混編只要注意將包含C++代碼的.m文件改為.mm即可,XCode就會自動判斷該使用何種編譯器來編譯。

這看起來簡單,但實際操作中還是很容易出現令人費解的編譯問題,比如最經典的"Unknow type name ‘class’; did you mean ‘Class’?“。究其原因就是我們沒有遵守這兩條規則:

  • .m文件不能含有C++代碼
  • .m文件所import或include的.h文件中不能直接或間接包含C++代碼

在保證你的C++代碼是正確前提下,如果發現相關編譯錯誤可以通過如下幾個方法修復

  1. 將.h文件中的c++代碼轉移到其他地方
  2. 阻段include或import鏈
  3. 將相關的.m文件後綴改成.mm

顯然第三種方法相對於前兩種實施起來更方便,但如果你使用XCode 4以及之後的版本所包含的模板建立項目的話有可能會忽視一個問題:

當你在AppDelegate.h中include或import一個C++的頭文件時,當然你一定不會忘記修改AppDelegate.m為AppDelegate.mm,如果只做了這點兒還不夠,我們還忽略了隱藏在Supporting Files組內的一個文件的存在–main.m

在以前的XCode模板中main.m默認是這樣的

#import <UIKit/UIKit.h>;
 
int main(int argc, char *argv[]) {
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

而新的模板是這樣的:

#import <UIKit/UIKit.h>;
 
#import "AppDelegate.h"
 
int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

看出問題來了吧,main.m新增了#import “AppDelegate.h",這就導致了main.m作為一個Objective-C源文件卻引入了C++代碼,而Xocde會使用Objective-C的編譯器進行編譯,從而產生編譯錯誤,因此我們還需要將main.m的後綴改成.mm。
 
總結+吐槽:我在發現main.m這個問題之前對編譯錯誤糾結了好久,一度修改代碼,也一度懷疑是XCode本身的問題(XCode 4出奇的不穩定讓人不得不對其產生質疑,雖然這次是我錯了),希望同樣使用Objective-C++的同學不要像我一樣栽在main.m上。

Copyright © Linux教程網 All Rights Reserved