有没有办法调用从Swift的dylib加载的C函数?
这是我的 dylib 文件:
cppdemofile.cpp
#include "cppdemofile.h" int add(int a, int b) { return a + b; }
cppdemofile.h
#ifndef __CppDemoLibrary__cppdemofile__ #define __CppDemoLibrary__cppdemofile__ #pragma GCC visibility push(default) extern "C" int add(int a, int b); #pragma GCC visibility pop #endif
编译为dylib并检查:
nm -gU libCppDemoLibrary.dylib 0000000000000f80 T _add
…复制libCppDemoLibrary.dylib到~/lib…
libCppDemoLibrary.dylib
~/lib
Swift程序 :
@IBAction func buttonClick(sender: NSButton) { let handle = dlopen("libCppDemoLibrary.dylib", RTLD_NOW) if (handle != nil) { var sym = dlsym(handle, "add") if (sym != nil) { let pointer = UnsafeMutablePointer<(CInt, CInt) -> CInt>(sym) // When debugging, I'm reaching up to this point... // but now, how do I call the 'add' function here??? // var result = ??? // label.stringValue = "Total: " + String(result) } } }
如何调用该add函数?可以使用dylib吗?我应该改为将这些资源添加到我的迅速项目中吗?
add
add从Swift 调用该函数是可能的,因为您已将其定义为与C关联extern "C"。
extern "C"
使库成为Swift模块(如上述注释中的jtbandes所建议)可能是更好的解决方案,但是这是您可以使用dlsym()Swift所返回的函数指针的方法:
dlsym()
首先添加
typedef int(*addFunc)(int, int);
到桥接头文件,或者定义
typealias addFunc = @convention(c) (CInt, CInt) -> CInt
在Swift中。然后进行以下工作:
let handle = dlopen(path, RTLD_NOW) if (handle != nil) { var sym = dlsym(handle, "add") if (sym != nil) { let f = unsafeBitCast(sym, addFunc.self) let result = f(12, 45) print(result) } dlclose(handle) }
当然,如果addFunc与所加载函数的实际签名不匹配,这将导致崩溃。
addFunc
Swift 3 更新 :
if let handle = dlopen(path, RTLD_NOW) { if let sym = dlsym(handle, "add") { let f = unsafeBitCast(sym, to: addFunc.self) let result = f(12, 45) print(result) } dlclose(handle) }