使用C、C++、Objective-C三语言混编时的注意事项

 C++和C混编: 
    1. auto关键字在C++11后改变了含义,如果C代码中有出现auto关键字,拷贝到.cpp中一定要将所有的auto删除  
       
      int a = 8;
      register int b = 9;
      auto int c = 10; // 在.cpp中应该删除这里的auto
      static int d = 11;



    2. const关键字,如果在C语言中被用来声明一个外部const量,拷贝到.cpp中需要添加extern关键字
       
      const int a; // C语言中用作声明一个外部const量a在.cpp文件中会报错
      const int b = 9; // 定义一个const量
      extern const int c; // 声明一个外部const量c





       

    3. 如果需要在.c文件中调用.cpp文件中的函数,必须在定义该函数是添加extern "C"
       
      // .cpp
      extern "C" void func1() { // 此函数将以C语言形式编译
      }
      void func1(int a) { // 在cpp中仍可将函数重载,但是不可将重载函数也声明成C函数
      }
      // .c
      void func1(); // 正常声明
      void func2() {
          func1(); // 可以调用.cpp中的函数
      }













       

    4.  在.cpp文件中调用C语言头文件时,如果按照原始方式(.h)来调用,则会与在C语言中使用完全相同,如果采用兼容形式(c*),部分函数将会有重载或重写
       

      // 原始方式
      #include <math.h>
      void func1() {
          int a = abs(4); // 必须传整型
          double b = fabs(3.5); // 必须传浮点型
      }
      // 兼容方式
      #include <cmath> // 包含了STL对<typename T>std::abs(T num)的定义
      void func2() {
          int a = std::abs(4); // 可以传整型
          double b = std::abs(7.5); // 也可以传浮点型
      }














       
 Objective-C和C++混编(基本原则就是把.m文件当成.c文件来看待,道理同上)
    1. 在一个.mm文件中可以同时出现Objective-C代码和C++代码,两者语法互不影响,但是继承不可混用
       
      #import <Foundation/Foundation.h>
      #import <iostream> // 可以使用import来包含STL库头文件,但是此时不能自动处理重复包含,效果与include完全相同
      class CppClass; // C++类按照C++类的声明来书写,所以这里不能写作@class,如果是声明OC类则需要写@class
      @interface OCClass : NSObject /*不能让OCClass继承自std::string等C++类*/ {
          CppClass *_cp; // 成员中可以定义指向C++对象的指针,但不能直接定义C++对象,并且该指针不能通过@property来自动生成getter和setter,需要手动书写
      }
      @property int men1;
      - (void)show;
      @end
      class CppClass {
      public:
          int men;
          OCClass *op; // 这里也可以定义指向OC对象的指针
          CppClass(int men):men(men) { // 指向OC对象的指针无法写入初始化列表,因此不能将该指针声明为const成员
              op = [[OCClass alloc] init]; // 只能在函数体中来初始化
          }
          friend std::ostream &operator <<(std::ostream &stream, CppClass &temp) {
              NSLog(@"%d\t%@", temp.men, temp.op); // 可以调用Cocoa框架中的方法,但传参时只能传OC对象以及C语言的数据类型,不可以将C++对象(例如std::string)传入OC函数
              return stream;
          }
      };
      @implementation OCClass
      - (NSString *)description {
          return [NSString stringWithFormat:@"%d", self.men1];
      }
      - (instancetype)init {
          if (self = [super init]) {
              _cp = new CppClass(1); // 由于不能定义成员对象,只能定义指针,因此需要在初始化方法中使用new来创建C++对象
          }
          return self;
      }
      @end








































    2. 如果在.mm中书写普通函数,则默认为C++函数,不能够在.m文件中直接调用,否则需要加上extern "C"。
    3. 如果需要.m文件和.cpp 文件对接,有两种方法: 
        1. 书写C语言函数(注意在.cpp中需要按照C方式定义,加上extern "C"关键字)作为接口,进行C语言类型数据的传递; 
        2. 书写一个.mm文件作为接口,将C++对象包装到OC类中使得.m文件可以调用,将OC对象包装到C++类中使得.cpp文件可以调用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章