> On Oct 4, 2017, at 11:02 AM, Ján Kosa via swift-users <swift-users@swift.org> 
> wrote:
> 
> Hello folks,
> 
> I have been toying with dynamic libraries, trying to implement plugin 
> functionality. I was able to get to the point where I can call simple 
> function in loaded library, but I am having troubles starting more 
> sophisticated communication channel.
> 
> There are 3 projects
> - PluginConsumer is an app that loads plugin libraries 
> - MyPlugin is a plugin implementation, output is dynamic library that 
> PluginConsumer loads
> - PluginInterface is common interface that both MyPlugin and PluginConsumer 
> use, so that they know how to communicate
> 
> My first idea was to have PluginInterface be a simple SPM project with single 
> file where the bare-bones PluginInterface class would be:
> 
> 
> open class PluginInterface {
> 
>     open func sayHi()
> 
> }
> 
> 
> 
> Package.swift file:
> 
> 
> 
> // swift-tools-version:4.0
> 
> import PackageDescription
> 
> let package = Package(
> 
>     name: "PluginInterface",
> 
>     products: [ .library(name: "PluginInterface", type: .dynamic, targets: 
> ["PluginInterface"]) ],
> 
>     targets: [ .target(name: "PluginInterface") ]
> 
> 
> )
> 
> 
> 
> 
> 
> UserPlugin is also very simple project containing only one file:
> 
> 
> 
> public func getPlugin() -> AnyObject {
> 
>     return MyPlugin()
> 
> 
> }
> 
> 
> 
> class MyPlugin: PluginInterface {
> 
>     override func sayHi() {
> 
>         print("Hi from my plugin")
> 
>     }
> 
> }
> 
> Package.swift:
> 
> 
> 
> // swift-tools-version:4.0
> 
> import PackageDescription
> 
> let package = Package(
> 
>     name: "MyPlugin",
> 
>     products: [ .library(name: "MyPlugin", type: .dynamic, targets: 
> ["MyPlugin"]) ],
> 
>     dependencies: [ .package(url: "url_to_PluginInterface", from: "0.0.0"), ],
> 
>     targets: [
> 
>         .target(name: "PluginInterface", dependencies: ["PluginInterface"]),
> 
>         .target(name: "MyPlugin", dependencies: ["PluginInterface"]),
> 
>     ]
> 
> 
> )
> 
> 
> 
> The PluginConsumer is bit more complicated, but here is relevant part (lib 
> loading and function calling):
> 
> 
> 
> typealias InitFunction = @convention(c) () -> AnyObject
> 
> 
> 
> let openRes = dlopen(pathToLib, RTLD_NOW|RTLD_LOCAL)
> 
> if openRes != nil {
> 
>     defer {
> 
>         dlclose(openRes)
> 
>     }
> 
>     let symbolName = "mangled_symbol_name"
> 
>     let sym = dlsym(openRes, symbolName)
> 
> 
> 
>     if sym != nil {
> 
>         let f: InitFunction = unsafeBitCast(sym, to: InitFunction.self)
> 
>         let plugin = f() as? PluginInterface
> 
>     }
> 
> 
> }
> 
> Package.swift file:
> 
> // swift-tools-version:4.0
> 
> import PackageDescription
> 
> let package = Package(
> 
>     name: "PluginConsumer",
> 
>     dependencies: [ .package(url: "path_to_plugin_interface", from: "0.0.0") 
> ],
> 
>     targets: [ .target(name: "PluginConsumer", dependencies: 
> ["PluginConsumer"]) ]
> 
> 
> )
> 
> 
> 
> This all compiles nicely, MyPlugin project creates dylib file that executable 
> created by PluginConsumer can load, but the problem is with following line:
> 
> let plugin = f() as? PluginInterface
> 
> Type of the plugin is MyPlugin, but from the consumer's view, it doesn't 
> inherit from PluginInterface so I can't call sayHi() method. I assume this is 
> because there is no relation between PluginInterface class that compiler uses 
> for MyPlugin project one that it uses for PluginConsumer project. After 
> library is loaded, they are two completely different classes that happen to 
> share same name. Is my assumption correct and how do I go about fixing it?

It sounds like that may be the case. Class names are namespaced to their 
module. If you're literally including the same PluginInterface.swift file in 
both of your modules, then you're going to end up with a 
ModuleA.PluginInterface and ModuleB.PluginInterface class. If you built 
PluginInterface as its own module, and imported the same module from your 
plugin and host projects, then you should end up with one common class.

-Joe

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to