在上一篇文章macOS项目中引入c静态库中,为阐述了如何在macOS项目中引入c语言的静态库,但是这样做有一个问题,就是静态库中的代码报错,会无法定义报错的位置,进而不利于排查问题。为了解决这个问题,我修改为源码引入c语言库。
很多教程中都提到,要引入c语言库的源码,需要将源码和头文件都拷贝到macOS项目的目录中,这样做,有一个弊病,就是对于需要引入c语言库的项目,通常都是想底层多平台支持,底层代码就需要独立于任何一个平台代码,如果要拷贝到macOS项目中,那后续修改和维护都会比较麻烦,实际上这是不需要的,接下来就阐述一下我这两天的实践。
一、项目结构
我们准备两个示例项目,其中项目A是基于swift构建的macOS项目,项目B是基于cmake构建的c语言项目。其目录树如下:
1 | A/ |
1 | B/ |
library的头文件和代码文件如下:
1 |
|
1 |
|
这里c代码文件中,故意制造了一个空指针崩溃,以便于测试定位崩溃位置。
二、macOS项目引入c语言源代码项目
在XCode中,A项目的根目录下,右键-Add Files to “A”,然后选择项目B的根目录选择的时候,千万不要勾选“Copy items if needed”,然后点击Add,如此操作之后,你会在XCode的项目目录中,看到在根目录下多了一个名为B的Group,但是这个Group并不会出现在实际的文件目录下。那在XCode中,项目A的目录结构变成了如下这样:
1 | A/ |
三、创建桥接文件
与静态库方案类似,也需要创建一个桥接文件,名为A-Bridging-Header.h,放置在根目录下,然后在Build Settings下搜索Header Search Paths设置项,在Debug和Release下,设置B库的include目录,注意:因为B库并未实际在A项目的文件目录下,所以,你不能设置一个A项目下的目录。我设置的值为:$(SRCROOT)/../B/include
。增加此配置后,在桥接文件中,增加头文件的引入,内容如下:
1 |
还差最后一步,把桥接文件设置到Objective-C Bridging Header配置中,由于桥接文件在根目录下,所以我设置的值为A-Bridging-Header.h
。
四、运行
在AApp.swift代码中,我们创建一个Application Delegate,代码如下:
1 | import SwiftUI |
当应用启动时,调用一下c语言中get_id
这个方法,由于方法中有一个空指针错误,会触发崩溃,并指向崩溃位置。
后记
在现实项目中,c源码项目可能远比demo中的要复杂的多,引入源码后,可能会引起类似于如下的编译错误:
1 | xcode macOS项目中,引入了第三方的c语言库后,出现了这样的错误,似乎是因为不能识别这些文件造成的,我把这些文件的引用从xcode删除后,就没有这些错误了,请问情况是这样的吗?以下是错误的内容: |
如果发生了这个错误,需要在Build Phases中,找到Copy Bundle Resources选项,点击底部”-“号按钮,删除掉重复的项,如果重复的项过多,这个按钮会被顶到列表最下边。
Author: boybeak