在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. Windows 8.1 应用再出发 - 几种新增控件(1)

    Windows 8.1 新增的一些控件,分别是:AppBar.CommandBar.DatePicker.TimePicker.Flyout.MenuFlyout.SettingsFlyout.Hub ...

  2. 利用sklearn进行tfidf计算

    转自:http://blog.csdn.net/liuxuejiang158blog/article/details/31360765?utm_source=tuicool 在文本处理中,TF-IDF ...

  3. [Xamarin] 透過WebClient跟網路取得資料 (转帖)

    之前寫過一篇文章,關於在Android上面取得資料 透過GET方式傳資料給Server(含解決中文編碼問題) 我們來回顧一下 Android 端的Code: 有沒有超多,如果是在Xaramin下面,真 ...

  4. Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)

    前言 很久没更新博客了,加上刚过年,现在准备重新开战,继续自己的学习之路.本文已同步到Web API2系列文章中http://www.cnblogs.com/aehyok/p/3446289.html ...

  5. Lambda应用设计模式

    前言 在使用 Lambda 表达式时,我们常会碰到一些典型的应用场景,而从常用场景中抽取出来的应用方式可以描述为应用模式.这些模式可能不全是新的模式,有的参考自 JavaScript 的设计模式,但至 ...

  6. Oracle 删除大表中部分数据

    需求: 项目中有一张表大概有7000多万条数据,造成表空间已满,需要清理部分数据,打算清理3000万. 2B 做法: delete from table_name where ID > '400 ...

  7. 在console中输出图片

    console.log("%c\n ","font-size:81px;background:url('http://www.baidu.com/img/bdlogo.g ...

  8. 一道印象深刻的面试题:String参数传递问题

    今天小菜去北京某知名公司面试,做了公司的面试题,然后就是轻松的面试. 面试过程中,面试官让我讲讲其中一个题是怎么选的答案,代码大致内容如下: public class StringTest{ publ ...

  9. js常规日期格式处理、月历渲染、倒计时函数

    日期格式处理在前端的日常任务中非常常见,但是为此引入monent.js这样的类库又会显得有点臃肿,毕竟我们一个特定的项目中,并不需要monent.js那么全的涵盖范围.另外,如果现在公司让你自己手写一 ...

  10. Atitit.实现反向代理(1)----url rewrite 配置and内容改写 and -绝对路径链接改写 java php

    Atitit.实现反向代理(1)----url rewrite  配置and内容改写 and -绝对路径链接改写 java php 1. 代理的实现:::普通代理and反向代理?? 1 2. url  ...