Swift: 如何调用从 dylib 加载的 C 函数
Swift: How to call a C function loaded from a dylib
有没有办法调用从 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, 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可以吗?我是否应该将这些资源添加到我的 swift 项目中?
为了在 Swift 中使用 C++ 代码,您需要将其包装在 C 函数中或 Objective-C 类.
另见Call a C++ function from Swift
可以从 Swift 调用 add
函数,因为您
将其定义为与 extern "C"
.
具有 C 链接
使库成为一个 Swift 模块(如上面 jtbandes 所建议的那样
评论)可能是更好的解决方案,
但这里是如何使用函数指针 return by dlsym()
from Swift:
先加
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
与
加载函数的实际签名。
Swift3 的更新:
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 的 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, 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可以吗?我是否应该将这些资源添加到我的 swift 项目中?
为了在 Swift 中使用 C++ 代码,您需要将其包装在 C 函数中或 Objective-C 类.
另见Call a C++ function from Swift
可以从 Swift 调用 add
函数,因为您
将其定义为与 extern "C"
.
使库成为一个 Swift 模块(如上面 jtbandes 所建议的那样
评论)可能是更好的解决方案,
但这里是如何使用函数指针 return by dlsym()
from Swift:
先加
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
与
加载函数的实际签名。
Swift3 的更新:
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)
}