首页 > 解决方案 > 是否可以在 Swift 中创建一个可以与 C 代码链接和调用的函数?

问题描述

我有大量用 Swift 编写的代码(在 macOS 上),我希望将其提供给用 C 编写的其他代码。具体来说,我想在 Swift 中创建一些胶水代码,它导出了许多具有 C 调用约定和未损坏的函数名称,并调用相关的 Swift 代码。

是否可以创建一个 Swift 文件,其中包含一个名为的函数,比如说,foo它看起来像:

func foo() → () {
    print("This is in Swift");
    /// call other Swift code here
}

当编译swiftc成一个.o文件时,它可以与一个包含以下内容的 C 文件链接:

extern void foo();

...

void bar() {
   ...
   printf("This is in C\n");
   foo();
   ...
}

?

默认情况下,Swift 函数名称与类型数据混合在一起,虽然@convention(c)Swift 中有一个属性,但它似乎不能用于函数声明,而只是在 Swift 中传递给 C 代码的回调。有没有办法让 Swift 代码与 C 链接并从 C 中调用?

标签: cswift

解决方案


这是@_cdecl应该允许你做的。它在大多数情况下都能正常工作,但要正确使用可能会很棘手。您将其应用于顶级函数,并且所有参数和返回类型都必须对 C 和 Swift 可见。

因此,在这种情况下,您可以像这样将其添加到 foo 中:

@_cdecl("foo")
func foo() ...

然后,这将为foo()您的符号提供 Swift 和 C 名称。唯一另一个棘手的部分是获取链接和运行时间。您可能希望在 Swift 中启动您的可执行文件,以便运行时在那里,但可以在 C 中启动它。也就是说,我只做了一次实验,不记得我必须传递的所有标志在 C 领域开始时工作的东西。


推荐阅读