当前位置: 首页 > 面试题库 >

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

范峰
2023-03-14
问题内容

有没有办法调用从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吗?我应该改为将这些资源添加到我的迅速项目中吗?


问题答案:

add从Swift 调用该函数是可能的,因为您已将其定义为与C关联extern "C"

使库成为Swift模块(如上述注释中的jtbandes所建议)可能是更好的解决方案,但是这是您可以使用dlsym()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与所加载函数的实际签名不匹配,这将导致崩溃。

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例程? 许多iOS / Apple库仅是C语言,我仍然希望能够调用它们。 例如,我希望能够从Swift调用objc运行时库。 特别是,如何桥接iOS C标头? 问题答案: 是的,您当然可以与Apples C库进行交互。这里说明了如何。 基本上,C型,C指针等被翻译成对象斯威夫特,例如C 在夫特是一个。 我为另一个问题构建了一个小例子,该例子可以作为对C和Sw

  • 问题内容: 我有一个旧的Objective-C项目,我想调用新的Swift函数和对象,我已经创建了文件“ ”和“ ” 对我来说,从Swift调用函数到Objective-C很容易,但是我有一个反向问题。 因此,我创建了一个简单的类“ System.Swift” 现在我尝试按照此处和文件内的文档进行操作 并且已将其导入到Objective-C类中。此时,在我的Objective-C代码的Object

  • 问题内容: 我想从JavaScript 调用,这是一个C#函数。我尝试了下面的代码,但是无论JavaScript条件是还是,都被调用了! JavaScript代码: 后面的C#代码: 如何从JavaScript调用C#函数? 问题答案: 您可以使用Web方法和Ajax:

  • 问题内容: 我需要从Java调用C#函数,为此,我创建了以下代码。我有一个创建的Java头文件Authenticator.h,代码如下: 然后,我创建了一个身份验证的C#函数 然后,我尝试使用以下代码从C ++(项目创建dll)中调用C#函数; 最后创建一个需要从Java调用的dll。该dll已创建,并且可以在Java中很好地加载它,但是在Java中却收到此错误日志。我可能会错过什么。 问题答案:

  • 问题内容: 如何从C ++应用程序调用Java函数? 我知道从CMD(或类似技术)调用它们的方法,但我宁愿不使用它们。 问题答案: 例如,检查从C创建JVM。它显示了创建JVM和调用方法的示例过程。如果JVM已经存在;例如,您的C程序被Java程序调用(回调情况),则可以缓存JNIEnv *指针。 作为建议,请小心从C / C ++缓存指向JVM的指针,其中涉及到一些有关可以缓存的内容的语义,以后

  • 我在plpgsql中创建了一个函数,我试图从. net核心api调用存储过程,但我在c#中得到了以下异常 42883:功能程序插入测试(brndcode= 没有函数匹配给定的名称和参数类型。可能需要添加显式类型转换。 程序: 从c#调用过程: 会有什么问题?