动态库与静态库(二)

库与库的连接有下列四种形式,下面分别进行项目演示:c++

动态库连接动态库

App连接动态库,动态库连接AFNetworking 1.建立工程MyApp 2.添加一个Target,选择Frameworkmarkdown

图片.png 3.在MyApp目录下建立Podfile,在target 'MyDylib' do下添加以下代码:ui

target 'MyDylib' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MyDylib
  pod 'AFNetworking'

end
复制代码

4.从新使用xcworkspace打开项目,在MyDylib添加文件:spa

图片.png

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyDyLibTest : NSObject
-(void)myDyLibTest;
@end

NS_ASSUME_NONNULL_END
复制代码
#import "MyDyLibTest.h"
#import<AFNetworking.h>
@implementation MyDyLibTest
-(void)myDyLibTest
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
}
@end
复制代码

5.将头文件拖到指定位置3d

图片.png 6.ViewController.m中添加调用代码:code

#import "ViewController.h"
#import <MyDylib/MyDyLibTest.h>

@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
    
    // Do any additional setup after loading the view.
}


@end
复制代码

7.Scheme选择MyApp运行工程orm

图片.png

提示的信息说明了,按照MyDylib保存的@rpath路径找,找不到AFNetworking图片

动态库MyDylibApp正常连接,可是动态库AFNetworking并不在动态库MyDylib保存的@rpath与动态库AFNetworkinginstall_name的组合路径下ip

动态库AFNetworking的路径 = MyDylib@rpath + 动态库AFNetworkinginstall_nameget

解决方法有两种分别是:

  • 第一种是拷贝到动态库AFNetworking到指定路径下。

在主工程target添加pod 'AFNetworking'从新pod一下。 这种方式能解决问题是由于在Pods-MyApp-frameworks.sh这个文件中,已经经过脚本进行拷贝了

if [[ "$CONFIGURATION" == "Debug" ]]; then
  install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
  install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
fi
复制代码
  • 第二种是修改动态库MyDylib@rpath为动态库AFNetworkinginstall_name以前的绝对路径

图片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
复制代码

经过以上两种方式都可以解决问题。

图片.png

动态库反向调用App代码

1.建立App项目的类,并作相关配置

图片.png

图片.png

图片.png 2.动态库调用App代码

#import "MyDyLibTest.h"
#import<AFNetworking.h>
#import "MyAppClass.h"
@implementation MyDyLibTest
-(void)myDyLibTest
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
    
    MyAppClass *cls = [MyAppClass new];
    NSLog(@"MyAppClass===%@",cls);
}
@end
复制代码

3.远行项目报错

图片.png 解决办事是告诉连接器动态查找。使用xcconfig配置:

在动态库MyDyLib下建立

图片.png

图片.png

图片.png

本身建立的xcconfig文件中导入Pod建立的xcconfig文件

图片.png 可以使用如下参数:

-undefined

图片.png 这种方式有个问题,就是其它为定义的符号都不会报错

-U symbol_name

图片.png 这种方式只是针对指定符号,忽略报错信息 修改后运行项目:

图片.png

App调用动态库AFNetworking代码

  • 第一种方式就是直接让MyApp工程下podAFNetworking
  • 第二种方式是经过设置FRAMEWORK_SEARCH_PATHS

图片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
复制代码

动态库连接静态库

1.配置工程和上一个例子基本同样,不一样的是在Podfile是使用静态库

target 'MyDyLib' do
  # Comment the next line if you don't want to use dynamic frameworks
  # use_frameworks!

  # Pods for MyDyLib
 pod 'AFNetworking'
end
复制代码

use_frameworks!前面的#号不能去掉 2.ViewController.m代码以下:

#import "ViewController.h"
#import <MyDyLib/MyDyLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
}
复制代码

直接可以运行成功

图片.png 缘由是在编译动态库的时候会把它依赖的静态库连接到动态库中,因此不会报错

3.App使用静态库里的代码

#import "ViewController.h"
#import <MyDyLib/MyDyLib.h>
#import <AFNetworking/AFNetworking.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
    
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
}
复制代码

图片.png 头文件找不到,须要配置一下Header Search Paths

图片.png 配置完成后,运行

图片.png

静态库连接静态库

1.配置工程,参照前两个配置,建立静态库的时候修改一下这个地方

图片.png 2.相关代码: MyStaticLibTest代码:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyStaticLibTest : NSObject
-(void)testMyStaticLib;
@end

NS_ASSUME_NONNULL_END

复制代码
#import "MyStaticLibTest.h"
#import <AFNetworking/AFNetworking.h>
@implementation MyStaticLibTest
-(void)testMyStaticLib
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"testMyStaticLib===%@",manager);
}
@end

复制代码

ViewController.m代码

#import "ViewController.h"
#import <MyStaticLib/MyStaticLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyStaticLib *lib = [MyStaticLib new];
    [lib testMyStaticLib];
}
@end
复制代码

3.远行报错

图片.png

分析:App去连接静态库的时候是没有问题的,可是当静态库去链家静态库AFNetworking的时候,会有问题。由于这个静态库AFNetworking并无合并到我本身建立的静态库中,App不知道它在哪。 解决方式:

  • 告诉App,静态库AFNetworking在哪

图片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
复制代码

配置完成后远行程序 图片.png

静态库连接动态库

1.工程配置,参考以上配置 2.相关代码: MyStaticLibTest代码:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyStaticLibTest : NSObject
-(void)testMyStaticLib;
@end

NS_ASSUME_NONNULL_END
复制代码
#import "MyStaticLibTest.h"
#import <AFNetworking/AFNetworking.h>
@implementation MyStaticLibTest
-(void)testMyStaticLib
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"testMyStaticLib===%@",manager);
}
@end
复制代码

ViewController.m代码:

#import "ViewController.h"
#import <MyStaticLib/MyStaticLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyStaticTest *lib = [MyStaticTest new];
    [lib testMyStaticTest];
}
@end
复制代码

3.运行报错

图片.png

告诉App动态库AFNetworking在哪

图片.png

又出现了熟悉的错误

图片.png 这个路径下找不到动态库AFNetworking,按照提示路径进去看一下

图片.png 缺乏了上面红色颜色的库

4.使用脚本将动态库AFNetworking拷贝到当前路径下

podAFNetworking动态库中的项目中拷贝一个以.sh结尾的文件,放到项目根目录

图片.png

Run Script内配置正确的路径

图片.png 图片.png

5.编译运行

图片.png 已经拷贝过来了,也正常运行了

图片.png

静态库生成的时候只保存了动态库的名称,App连接静态库后,会把静态库全部的代码都连接进去,可是App不知道动态库的位置。

相关文章
相关标签/搜索