Swift:如何调用从dylib加载的C函数

有没有办法调用从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

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>(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从Swift调用add函数,因为您将其定义为与extern "C"具有C链接。

使库成为一个Swift模块(正如上面评论中的jtbandes所建议的)可能是更好的解决方案,但是这里是如何使用来自Swift的dlsym()返回的函数指针:

首先添加

 typedef int(*addFunc)(int, int); 

到桥接头文件,或者定义

 typealias addFunc = @convention(c) (CInt, CInt) -> CInt 

在斯威夫特。 然后以下工作:

 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与加载的函数的实际签名不匹配,这将会崩溃。


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) } 

为了在Swift中使用C ++代码,您需要将其包装在C函数或Objective-C类中。

另请参阅从Swift调用C ++函数