从swift中动态加载的框架启动类

时间:2018-03-30 10:41:27

标签: swift dynamic frameworks dlopen

以下是关于我的问题的一些背景信息。

我的自定义开发框架(" Custom.framework")必须动态加载第三方框架(" Dynamic1.framework"" Dynamic2.framework") dlopen的。我需要这个的原因是我应该支持这些框架提供的一些功能的几个实现,这些功能基于客户端应用程序中使用的框架(使用我的自定义框架)。

我的框架的某些部分也是用ObjC编写的,而其他部分则是使用Swift编写的。 从Objc调用Dynamic1.framework,从Swift调用Dynamic2.framework。 使用来自ObjC的Dynamic1我没有问题:我已经为我使用的类创建了协议包装器,使用dlopen加载框架,然后实例化。我在下面的代码中写道:

#import "dlfcn.h"

@protocol Dynamic1ClassProtocol
+ (nullable instancetype)shared;
- (void)doSmth;
@end

void *frameworkHandle = dlopen("Dynamic1.framework/Dynamic", RTLD_LAZY);
Class x = NSClassFromString(@"Dynamic1Class");
if (x)
{
      NSObject <Dynamic1ClassProtocol> *instance = [x shared];
      [instance doSmth];
}

但是我在使用swift加载的类时遇到了麻烦。我还使用方法创建了协议包装器,以模拟Dynamic2.framework中的实际类。我可以加载框架并获得&#39; Type&#39;来自框架的对象。但是我找不到如何真正实例化对象的方法。 这是代码:

@objc public protocol Dynamic2ClassProtocol: NSObjectProtocol {
    init()
}

let handle = dlopen("Dynamic2.framework/Dynamic2", RTLD_LAZY)
let x = NSClassFromString("Dynamic2Class")
if let type = x {
    let casted = type as! Dynamic2ClassProtocol.Type
    let instance = casted.init()
}

它编译但在运行时崩溃:

Could not cast value of type 'Dynamic2Class' (0x100f28670) to 'AppName.Dynamic2ClassProtocol' (0x100a832d0).

如果不使用强制转换而是使用强制转换,则它总是返回nil。 所以我不知道如何做到这一点。

此外,我还没有看到任何动态框架在swift doestn中工作的任何地方,所以可能我做错了。请帮忙

2 个答案:

答案 0 :(得分:1)

Dynamic2Class是NSObject的子类吗? (因为我认为这是NSClassFromString正常工作的要求。

您可以使用Bundle在运行时加载框架。请看这里的例子:

https://github.com/pendowski/SwiftPluginsExample

不确定dlopen与Swift的合作程度。我想知道是否有任何可以在Linux上运行

您还可以查看

https://github.com/apple/swift-corelibs-foundation/tree/master/CoreFoundation/PlugIn.subproj

这是为开源Swift基础实现的

答案 1 :(得分:0)

Swift类名称应包含模块名称。

let aClass = NSClassFromString("DynamicFramework.DynamicClassExample")