美文网首页
2023-07-11 通过58 fair源代码了解如何使用Dar

2023-07-11 通过58 fair源代码了解如何使用Dar

作者: 我是小胡胡123 | 来源:发表于2023-07-10 12:18 被阅读0次

1, fair 插件 是源代码

fair插件的 podspec中配置了一个动态库

  s.vendored_frameworks = 'FairDynamicFlutter/Products/FairDynamicFlutter.framework'

那么这里为什么做成动态库呢,而不像 插件的实现一样全部是源代码实现?

2, 我们看到这个 FairDynamicFlutter.framework 动态库的源代码也在fair项目里面

他的实现很简单。 就是实现了一个单例
方法的实现跳转到 代理执行。 等于是定义了一个 接口而已。

外面可以配置这个代理
按照代理的接口去落实具体的方法执行体。

/// FFI协议
@protocol FAIRFFIProtocol <NSObject>

/// 同步方法调用
/// @param args 参数
- (const char *)executeScriptSyncImpl:(char *)args;

@end

@interface FairDynamicFlutter : NSObject

@property (nonatomic, weak) id<FAIRFFIProtocol> delegate;

+ (instancetype)sharedInstance;

@end

那么这么做的目的是什么?

3,可以看到这个动态库,声明了一个c函数


/// 同步方法调用
FAIR_FFI_EXTERN const char *invokeJSCommonFuncSync(char *args);



const char *invokeJSCommonFuncSync(char *args) {
    if ([FairDynamicFlutter sharedInstance].delegate &&
        [[FairDynamicFlutter sharedInstance].delegate respondsToSelector:@selector(executeScriptSyncImpl:)]) {
        return [[FairDynamicFlutter sharedInstance].delegate executeScriptSyncImpl:args];
    }
    return "";
}

正式如此, 这就是使用dart 的 ffi 特性。 可以直接调用 c 代码 的能力。

所以才有了 为什么要专门做一个动态库。

这个动态库只是定义了一个delegate,暴露接口,由fair 插件中配置具体的方法实现。

这就完成了 dart 直接调用 ios c 代码的功能。

4, ios 中c代码如何被调用 dart ffi实现方法如下

首先在ios 这边做一个动态库,实现如下

使用宏定义,暴露出给 dart 层可见:

#if defined(__cplusplus)
#define FAIR_FFI_EXTERN extern "C" __attribute__((visibility("default"))) __attribute__((used))
#else
#define FAIR_FFI_EXTERN extern __attribute__((visibility("default"))) __attribute__((used))
#endif

c 代码的函数声明 部分,在头文件完成:
使用 extern "C" 表明这是 c 代码。 编译器在c++环境编译下,c++的函数符号编码 和 c 函数符号编码的不一样,使用extern c表示使用c的函数符号编译。
使用 attribute((visibility("default"))) attribute((used)) 这个就是 dart ffi 那边要求的暴露接口的声明方式,固定的模式。

/// 同步方法调用
FAIR_FFI_EXTERN const char *invokeJSCommonFuncSync(char *args);

c方法实现部分:


/// @param args 参数
/// @return 返回值
const char *invokeJSCommonFuncSync(char *args) {
    if ([FairDynamicFlutter sharedInstance].delegate &&
        [[FairDynamicFlutter sharedInstance].delegate respondsToSelector:@selector(executeScriptSyncImpl:)]) {
        return [[FairDynamicFlutter sharedInstance].delegate executeScriptSyncImpl:args];
    }
    return "";
}

在 dart 测实现代码如下:

使用 ffi 库, DynamicLibrary 系统对象。 完成对 c 代码 动态库的加载。 和c 方法函数的绑定。使用lookup 方法 查询c 代码的函数指针。

这样就实现了, dart 代码 c 代码的直接调用


import 'dart:convert';
import 'dart:ffi';
import 'package:ffi/ffi.dart';

 
final DynamicLibrary dl = Platform.isAndroid
    ? DynamicLibrary.open('libfairflutter.so')
    : DynamicLibrary.open('FairDynamicFlutter.framework/FairDynamicFlutter');


class FairMessageChannel {
  Pointer<Utf8> Function(Pointer<Utf8>) invokeJSCommonFuncSync = dl
      .lookup<NativeFunction<Pointer<Utf8> Function(Pointer<Utf8>)>>(
          'invokeJSCommonFuncSync')
      .asFunction();
 

  dynamic sendCommonMessageSync(dynamic msg) =>
      FairUtf8.fromUtf8(invokeJSCommonFuncSync.call(FairUtf8.toUtf8(msg)));
}

相关文章

网友评论

      本文标题:2023-07-11 通过58 fair源代码了解如何使用Dar

      本文链接:https://www.haomeiwen.com/subject/kxpeudtx.html