调用 C 动态库

由 王巍 (@ONEVCAT) 发布于 2015/11/04

C 是程序世界的宝库,在我们面向的设备系统中,也内置了大量的 C 动态库帮助我们完成各种任务。比如涉及到压缩的话我们很可能会借助于 libz.dylib,而像 xml 的解析的话一般链接 libxml.dylib 就会方便一些。

因为 Objective-C 是 C 的超集,因此在以前我们可以无缝地访问 C 的内容,只需要指定依赖并且导入头文件就可以了。但是骄傲的 Swift 的目的之一就是甩开 C 的历史包袱,所以现在在 Swift 中直接使用 C 代码或者 C 的库是不可能的。举个例子,计算某个字符串的 MD5 这样简单地需求,在以前我们直接使用 CommonCrypto 中的 CC_MD5 就可以了,但是现在因为我们在 Swift 中无法直接写 #import <CommonCrypto/CommonCrypto.h> 这样的代码,这些动态库暂时也没有 module 化,因此快捷的方法就只有借助于通过 Objective-C 来进行调用了。因为 Swift 是可以通过 {product-module-name}-Bridging-Header.h 来调用 Objective-C 代码的,于是 C 作为 Objective-C 的子集,自然也一并被解决了。比如对于上面提到的 MD5 的例子,我们就可以通过头文件导入以及添加 extension 来解决:

// TargetName-Bridging-Header.h
#import <CommonCrypto/CommonCrypto.h> // StringMD5.swift
extension String {
var MD5: String {
let cString = self.cStringUsingEncoding(NSUTF8StringEncoding)
let length = CUnsignedInt(
self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(
Int(CC_MD5_DIGEST_LENGTH)
) CC_MD5(cString!, length, result) return String(format:
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15])
}
} // 测试
print("swifter.tips".MD5) // 输出
// dff88de99ff03d109de22fed4f71a273

当然,那些有强迫症的处女座读者可能不会希望在代码中沾上哪怕一点点 C 的东西,而更愿意面对纯纯的 Swift 代码,这样的话,也不妨重新制作 Swift 版本的轮子。比如对于 CommonCrypto 里的功能,已经可以在这里找到完整的 Swift 实现了,如果你只是需要 MD5 的话,这里也有一个实现。不过如果可能的话,暂时还是建议尽量使用现有的经过无数时间考验的 C 库。一方面现在 Swift 还很年轻,各种第三方库的引入和依赖机制还并不是很成熟;另外,使用动态库毕竟至少可以减少一些 app 尺寸,不是么?

调用 C 动态库的更多相关文章

  1. c#调用c++动态库的一些理解

    调用c++动态库一般我们这样写   [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)] ...

  2. C#调用C++动态库(dll)

    在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用re ...

  3. C#总结(四)调用C++动态库

    由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...

  4. Java调用dll动态库

    最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...

  5. 【C#】 使用Gsof.Native 动态调用 C动态库

    [C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...

  6. python调用.net动态库

    # python调用.net动态库 ### pythonnet简介------------------------------ pythonnet是cpython的扩展- pythonnet提供了cp ...

  7. Delphi XE7调用C++动态库出现乱码问题回顾

    事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...

  8. 使用ctypes在Python中调用C++动态库

    使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #in ...

  9. C# 调用C++动态库注意事项

    C# 调用C++动态库注意事项 最近项目上需要在C#中调用C++,期间遇到不少坑,总结如下: 1.in const char*   对应C#中string 或  IntPtr 2.out const ...

  10. JNI_Android项目中调用.so动态库

    JNI_Android项目中调用.so动态库 2014年6月3日 JNI学习 參考:http://blog.sina.com.cn/s/blog_4298002e01013zk8.html 上一篇笔者 ...

随机推荐

  1. Educational Codeforces Round 18D(完全二叉树中序遍历&lowbit)

    题目链接:http://codeforces.com/contest/792/problem/D 题意:第一行输入n, q,分别表示给出一颗n个节点的中序遍历满二叉树,后面有q个询问; 接下来有q组形 ...

  2. 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:3. 订阅Topic与响应Topic

    文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...

  3. foreach循环报NPE空指针异常

    前言 最近debug时忽然发现,如果一个集合赋值为null,那么对该集合进行foreach循环(也叫增强for循环)时,会报NPE(即空指针异常NullPointerException). 代码如下: ...

  4. 序列化 jprotobuf

    jprotobuf工作原理如下: 扫描类上的注解的信息,进行分析(与protobuf读取proto文件进行分析过程相似) 根据注解分析的结果,动态生成java代码进行protobuf序列化与反序列化的 ...

  5. $.each(obj,function(index,value)遍历的学习

    JQuery遍历对象 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  6. tensorflow:实战Google深度学习框架第四章02神经网络优化(学习率,避免过拟合,滑动平均模型)

    1.学习率的设置既不能太小,又不能太大,解决方法:使用指数衰减法 例如: 假设我们要最小化函数 y=x2y=x2, 选择初始点 x0=5x0=5  1. 学习率为1的时候,x在5和-5之间震荡. im ...

  7. odoo filter 日期

    <!--日期--> <filter name="before_twodays" string="前天" domain="[('dat ...

  8. gin 打linux环境包问题解决

    打window包直接go build一下,完事, 但是,打linux包出现如下错误 ..\github.com\mattn\go-isatty\isatty_linux.go:7:8: cannot ...

  9. eclipse修改xml配置文件tomcat不能同步问题

    之前springmvc-config.cml中的Controller写成了Constroller,导致java.lang.ClassNotFoundException异常,而我更改后,更新的信息并没有 ...

  10. Android 滑动RecyclerView时隐藏部分控件

    在使用RecyclerView控件时,上下拖动控件时的时候,需要实时的隐藏与显示部分控件,已到达很好的用户体验.   原理很简单,当RecyclerView拖动至最上层时显示控件,当RecyclerV ...