• Objective-C和C/C++混合编译


    iOS开发过程中,Objective-C的代码有时需要调用C/C++代码,本篇文章介绍Objective-C如何混合编译C/C++。

    Xcode新建一个工程,选择macOS选项下面的Command Line Tool,工程命名为OCCppProject。

    Objective-C 调用C

    在工程中新建文件test.c文件,同时生成test.h文件,写入代码

    test.h

    #ifndef test_h
    #define test_h
    
    #include 
    
    #endif /* test_h */
    
    void testC();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    test.m

    #include "test.h"
    
    void testC()
    {
        printf("testC in called\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    新建TestOC文件,语言选择Objective-C,写入代码

    TestOC.h

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface TestOC : NSObject
    
    - (void)ocCallC;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    TestOC.m

    #import "TestOC.h"
    #include "test.h"
    
    @implementation TestOC
    
    - (void)ocCallC
    {
        testC();
    }
    
    @end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    main.m

    #import <Foundation/Foundation.h>
    
    #import "TestOC.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            TestOC *testOC = [[TestOC alloc] init];
            [testOC ocCallC];
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    main.m中文件引入TestOC.h文件,并且使用TestOC的实例调用ocCallC方法,这个方法调用了C的函数testC()

    代码可以正常编译和运行,所以Objective-C的代码可以直接调用C的函数,直接引入C的头文件,不需要额外改动。

    C调用Objective-C

    C语言的文件调用Objective-C,需要修改C文件的后缀为.m,修改test.C变为test.m

    test.h

    #ifndef test_h
    #define test_h
    
    #include 
    
    #endif /* test_h */
    
    void testC();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    test.m

    #include "test.h"
    #import "TestOC.h"
    
    void testC()
    {
        TestOC *testOC = [[TestOC alloc] init];
        [testOC ocMethod];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    TestOC.h

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface TestOC : NSObject
    
    - (void)ocCallC;
    - (void)ocMethod;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    TestOC.m

    #import "TestOC.h"
    #include "test.h"
    
    @implementation TestOC
    
    - (void)ocCallC
    {
        testC();
    }
    
    - (void)ocMethod
    {
        NSLog(@"ocMethod is called");
    }
    
    @end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    main.m

    #import <Foundation/Foundation.h>
    
    #import "TestOC.h"
    #include "test.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            testC();
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    代码可以正常编译和运行,C调用Objective-C,需要修改C语言文件的后缀为.m,引入OC的头文件后就可以正常使用了。

    Objective-C调用C++

    新建TestCpp.h和TestCpp.m文件,并且声明CPPObject类

    TestCpp.h

    #ifndef TestCpp_h
    #define TestCpp_h
    
    #include 
    #include 
    
    #endif /* TestCpp_hpp */
    
    
    class CPPObject {
    public:
        void testCpp();
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    TestCpp.m

    #include "TestCpp.h"
    
    
    void CPPObject::testCpp(){
        std::cout << "cpp function is called" <<std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    main.m

    #import <Foundation/Foundation.h>
    
    #import "TestOC.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            TestOC *testOC = [[TestOC alloc] init];
            [testOC ocCallCpp];
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Objective-C调用C++文件,需要修改文件后缀为.mm,然后引入头文件使用。

    C++调用Objective-C

    新建桥接文件CppOCInterface.h和CppOCInterface.mm

    CppOCInterface.h

    #ifndef CppOCInterface_h
    #define CppOCInterface_h
    
    #include 
    
    #endif /* CppOCInterface_h */
    
    void testBridge();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    CppOCInterface.mm

    #include "CppOCInterface.h"
    #import "TestOC.h"
    
    void testBridge()
    {
        TestOC *testOC = [[TestOC alloc] init];
        [testOC ocMethod];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Test.h

    #ifndef TestCpp_h
    #define TestCpp_h
    
    #include 
    
    #endif /* TestCpp_hpp */
    
    class CPPObject {
    public:
        void cppCallOC();
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Test.cpp

    #include "TestCpp.h"
    #include "CppOCInterface.h"
    
    void CPPObject::cppCallOC()
    {
        testBridge();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    main.mm文件

    #import <Foundation/Foundation.h>
    
    #import "TestOC.h"
    #include "TestCpp.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            CPPObject obj = CPPObject();
            obj.cppCallOC();
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    C++调用OC会比较麻烦,需要新建CppOCInterface文件作为桥接文件,桥接文件由于是.mm后缀的,所以桥接文件可以访问OC。

    C++调用桥接文件,桥接文件调用Objective-C,总体的流程是这样。

  • 相关阅读:
    LVS+keepalived高可用集群
    使用svnsync sync方法同步
    微信小程序:装B神器P图修改微信流量主小程序源码下载趣味恶搞图制作免服务器域名
    vulnhub——The Planets: Earth
    计算机、互联网基础系列-1-计算机基础、计算机网络基础知识汇总
    设置GIT代理
    RK356X/RK3588构建Ubuntu20.04根文件系统
    _getdrives获取不到网络磁盘
    关于自定义程序打包成jar包,并读取配置
    java毕业设计基于javaweb+mysql数据库实现的校园迎新(新生报道)网站含论文+开题报告
  • 原文地址:https://blog.csdn.net/u011608357/article/details/127466416