从C调用Swift的最佳方法是什么?

时间:2016-01-30 19:29:56

标签: c swift callback wrapper

从Swift调用C非常简单,但我正在研究在C中制作双向包装器,所以我的C必须调用Swift函数。

现在,我可以通过在C中声明函数指针来实现这一点,并且在Swift端将它们设置为在Swift中调用代码之后让我的C函数调用它们。

我的C头文件:

typedef void (*callback_t)(void);

void callBackIntoSwift( callback_t cb );

我的C实现文件:

#include "stuff.h"
#include <stdio.h>

void callBackIntoSwift( callback_t cb )
{
    printf( "Will call back into Swift\n" );
    cb();
    printf( "Did call back into Swift\n" );
}

在我的C头文件中包含我的C头文件后,我可以在Swift端执行以下操作:

let cb: callback_t = {
    someKindOfSwiftFunction()
}

callBackIntoSwift( cb )

甚至:

callBackIntoSwift {
    someKindOfSwiftFunction()
}

有没有更好的方法来做到这一点,不需要函数指针和回调?我想让C端直接调用someKindOfSwiftFunction ...但是当我尝试将@convention (c)应用于函数声明时,我得到的信息是该属性只能应用于类型,而不能应用于声明。

任何想法或代码库,例如: Github我可以看看吗?

2 个答案:

答案 0 :(得分:4)

根据Joe Groff

  

还没有官方的方法。除了名称修改之外,Swift函数使用来自C的不同调用约定。非正式地,如果您愿意处理超过通常的代码破坏和编译器错误的数量,那么有一个非官方属性@_cdecl执行此操作:

@_cdecl("mymodule_foo")
func foo(x: Int) -> Int {
  return x * 2
}
  

然后您可以从C:

调用
#include <stdint.h>

intptr_t mymodule_foo(intptr_t);

intptr_t invoke_foo(intptr_t x) {
  return mymodule_foo(x);
}

答案 1 :(得分:0)

您可以这样做:

FileSwift.swift

public class SwiftTest: NSObject {
    @objc public static func testMethod() {
        print("Test")
    }
}

FileSwiftWrapper.h

void SwiftFunctionWrapper();

FileSwiftWrapper.m

#import "ProductModuleName-Swift.h"

void SwiftFunctionWrapper() {
      [SwiftTest testMethod];
}