在Apple官方的《Using Swift with Cocoa and Objectgive-C》一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中使用Objective-C中的类。在后半部分也介绍了如何在Swift中使用C函数,不过对于如何在C语言中使用Swift函数却只字未提。这里我就为大家分享一下如何在C语言中调用Swift函数。

我们首先要知道的是,所有Swift函数都属于闭包。其次,Swift函数的调用约定与Apple为Clang编译器贡献的Blocks语法一致。因此,我们需要通过使用Blocks调用约定将Swift函数导入到C语言中。由于在C语言中无法直接声明Blocks调用约定的函数,因此我们可以通过定义全局的指向Blocks的对象指针来实现。

下面我们创建一个名为SwiftTest的macOS系统上的Swift工程。然后新建一个名为test.c的C源文件,如果Xcode没有弹出是否新建bridging-header文件,那么我们可以新增一个Objective-C源文件,最后把它给移除。这里,我们必须在工程里包含SwiftTest-Bridging-Header.h这个头文件。

然后我们编辑此头文件:

extern void (^ __nonnull SwiftFunc)(void);
extern void CFuncTest(void);

这里声明的全局指向void(^)(void)类型的Block的引用对象。

然后我们再看test.c源文件:

void (^SwiftFunc)(void) = NULL;

void CFuncTest(void)
{
SwiftFunc();
}

我们定义SwiftFunc全局对象,将它初始化为空。

然后在ViewController.swift中编辑以下内容:

// 这里是对SwiftFunc的实现
private func swiftFuncImpl() {
print("This is a Swift function!");
} class ViewController: NSViewController { override func viewDidLoad() {
super.viewDidLoad() // 这里对定义在test.c中的SwiftFunc进行初始化
SwiftFunc = swiftFuncImpl // 这里用dispatch_async来测试SwiftFunc是否一直被hold着
dispatch_async(dispatch_get_main_queue()) { CFuncTest()
}
}
}

当调用了test.c中定义的CFuncTest函数之后,该函数里将直接调用SwiftFunc这一Block引用对象,从而达到了在C语言中调用了Swift中函数的目的。

如何在C语言中调用Swift函数的更多相关文章

  1. 【转载】如何在C语言中调用shell命令

    转载自:http://blog.csdn.net/chdhust/article/details/7951576 如何在C语言中调用shell命令 在linux操作系统中,很多shell命令使用起来非 ...

  2. 解析如何在C语言中调用shell命令的实现方法【转】

    本文转自:http://www.jb51.net/article/37404.htm 1.system(执行shell 命令)相关函数 fork,execve,waitpid,popen表头文件 #i ...

  3. 小程序:如何在wxml页面中调用JavaScript函数

    早上过来遇到一个这样的bug: 在计算百分比的时候没有保留小数点后2位,从而导致一些无法整除的结果显示太长 一开始,我以为这是一个很普通的bug,既然wxml在页面{{}}内支持简单的运算,我想也应该 ...

  4. C语言中的自定义函数

    C语言中可以使用系统函数也可以使用自己的函数,就是自定义函数 自定义函数分为四种 第一种:无参无返回值的 函数的声明 void sayH(); 函数的实现 void sayH(){ printf(&q ...

  5. C语言中返回字符串函数的四种实现方法 2015-05-17 15:00 23人阅读 评论(0) 收藏

    C语言中返回字符串函数的四种实现方法 分类: UNIX/LINUX C/C++ 2010-12-29 02:54 11954人阅读 评论(1) 收藏 举报 语言func存储 有四种方式: 1.使用堆空 ...

  6. C语言中返回字符串函数的四种实现方法

    转自C语言中返回字符串函数的四种实现方法 其实就是要返回一个有效的指针,尾部变量退出后就无效了. 有四种方式: 1.使用堆空间,返回申请的堆地址,注意释放 2.函数参数传递指针,返回该指针 3.返回函 ...

  7. 在C#中调用Win32函数EnumWindows枚举所有窗口。

    原文 http://www.cnblogs.com/mfm11111/archive/2009/06/30/1514322.html 开发旺旺群发软件,难点及重要技术点分析(一) 一.        ...

  8. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  9. C语言中关于scanf函数的用法

    scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化 ...

随机推荐

  1. SpringMVC中使用DWR

    SpringMVC中使用DWR重点在其配置当中. 1.  web.xml文件的配置 在DispatcherServlet中增加dwr的拦截来取代DwrServlet. 更改配置如下: <serv ...

  2. 【Visual Lisp】Visual Lisp属性与方法

    说明:Visual Lisp属性的获取.赋值和方法的执行有多种形式.然而对于初学者来说一次性就要全部掌握显然是没有必要的,有时候每种方法都是通用的功能都一样我们就没有必要把所有方法都记住.我们只需要掌 ...

  3. HibernateTemplate和HibernateDaoSupport(spring注入问题)

    HibernateTemplate HibernateTemplate是spring提供的一个就hibernate访问持久层技术而言.支持Dao组件的一个工具.HibernateTemplate提供持 ...

  4. Debian修改ssh端口和禁止root远程登陆设置

    linux修改端口22vi /etc/ssh/sshd_config找到#port 22将前面的#去掉,然后修改端口 port 1234重启服务就OK了service sshd restart或/et ...

  5. Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

  6. Jpeg2000 简介

    http://www.baike.com/wiki/Jpeg2000 总结Jpeg2000的六个方面:    ⑴ JPEG2000可以方便地实现渐进式传输,这是JPEG2000的重要特征之一.看到这种 ...

  7. javascript和C#比较

    C#和javascript有很多相似的地方,比如: 序列化 C#序列化 首先需要引用 using System.Web.Script.Serialization;//System.Web.Extens ...

  8. ibatis + log4net 配置注意事项

    一 在web.config或app.config中配置 <configuration> <configSections> <sectionGroup name=" ...

  9. C++ 标准库类型-String,Vector and Bitset

    <C++ Primer 4th>读书摘要 最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合.这些标准库类型是语言组成部分中更基本的那些数据类型(如 ...

  10. JS几种数组遍历方式以及性能分析对比

    前言 这一篇与上一篇 JS几种变量交换方式以及性能分析对比 属于同一个系列,本文继续分析JS中几种常用的数组遍历方式以及各自的性能对比 起由 在上一次分析了JS几种常用变量交换方式以及各自性能后,觉得 ...