At a glance

软件开发中,可能需要把用到的资源文件嵌入到二进制执行文件中,例如生成单个执行文件、防止机密或版权信息被PE工具查看或修改、嵌入图片资源到静态库中等等。在Mac OSX Cocoa 或iOS开发中,编译生成的Product.app是一个APP包,其实就是个文件夹,右键Show Package Contents或者去掉 .app 扩展后双击打开就可以查看包内容,修改包里面的任何资源文件都不会影响程序正常运行,要提交到App Store的程序在修改资源文件后运行下codesign(安装Xcode时已经装了这个dev tool)重签名就可以了:

$ codesign -fvs "Your Identity" path/to/appfile.app

我之前写的 ElfCodeSigner 就是基于codesign的。

所以嵌入二进制资源文件也算是一种有效的保护手段。

结合我以前Windows开发中用到的措施,我想到了三种方案:

  • Base64编码。
    N久前在CSDN上给一个网友提供的方法,当时他的需求是对一些中英文字符串数据的编解码。我当时给出的Base64方案算是比较简便而且行之有效的。Base64方法同样适用于今天要讨论的嵌入资源问题。
    NSString 和 NSData可以互转,UIImage也提供了initWithData:的创建方法,所以将image data 进行base64编码后保存在一个NSString常量中,在用到时进行base64解码再[UIImage initWithData:]。
    此方法在处理很小的数据时比较有用,网上也有比较成熟的NSData+Base64类别类供使用。
  • PNG等资源的压缩加密
    经过加密处理的PNG图像用普通看图软件查看时只能看到一片透明或空白图带点斑点这样的无效图,但在程序运行时图像显示正常,这个加密方法在j2me、iOS等游戏和应用开发被大量使用。网上现成的加密工具很多,但可以被简单的逆向还原原图。
  • 转换成bytes数组。
    大多数资源嵌入都采用这种方案,原理很简单,把资源文件的每位字符转换成十六进制bytes[],几乎所有语言都提供了bytes[]到data的直接转换。
    大多数十六进制编辑器可以将hex结果保存为文件。被解密或修改比较困难,需要知道图形基本格式、熟练UE等十六进制编辑器、猜测、运气等。

最近公司项目中需要把一些图片资源嵌入到静态库中,我考虑了下还是用bytes的方法比较好,Cocoa原生支持其不会留下被修改的余地。一些简单的图标用CG画上去。这样公开出去的库只有一个.a文件和几个必要的.h文件。

下午闲着没事,就操起Xcode在新配的MacBook上写下了我这第一个跑在Mac OS上的C程序。

Release notes

rtb(Resource To Bytes)是一个命令行小工具,将二进制资源文件转换为bytes数组,方便在程序中使用嵌入资源。

由于时间仓促,rtb仅在Mac OS SL上测试过,对应应用在Mac OS桌面程序和iOS App中测试过,以后有时间再改成跨平台的。目前没发现什么bug。

使用方法:打开Terminal,cd到rtb所在目录,运行

$ ./rtb image.png

将生成

unsigned char image_png[] = { ..... };
unsigned int image_png_len = 16045;

变量名称根据资源文件名而来,数字开头的会加前缀 "__" ,文件名中非英文和数字的字符转换为下划线"_"(使用了isalnum()测试函数),在数组变量名称添加"_len"后缀作为数组长度变量名称。

例如"123te的 st5.png"将生成变量名unsigned char __123te____st5_png[] 和 unsigned int __123te____st5_png_len 。

Example

首先执行rtb生成.h文件:

$ ./rtb test.png > test.png.h

新建一个Window Base的iPhone项目,添加test.png.h文件到项目中,在
- (BOOL)application: didFinishLaunchingWithOptions:
方法中创建一个UIImage并把它添加到一个ImageView中:

 1 #import "test.png.h" 2  3 //............ 4 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 5 { 6     [self.window makeKeyAndVisible]; 7      8     unsigned char *imgBytes = test_png; 9     NSUInteger imgLenght = test_png_len;10     NSData *imgData = [NSData dataWithBytesNoCopy:imgBytes length:imgLenght freeWhenDone:NO];11     // UIImage *image = [UIImage imageWithData:imgData];12     // or13     UIImage *image = [[UIImage alloc] initWithData:imgData];14     15     UIImageView *imageView = [[UIImageView alloc] initWithImage:image];16     imageView.frame = self.window.frame;17     imageView.contentMode = UIViewContentModeCenter;18     [self.window addSubview:imageView];19     [imageView release];20     21     [image release];22     return YES;23 }

因为在程序加载时已经将test.png.h中的数组加载到内存中,所以使用NSData的dataWithBytesNoCopy方法即可,不需要再Copy一份,转换成NSData后也不需要释放它,所以freeWhenDonw参数值NO.

Code Review

我C语言很烂,就不贴代码了。注释、空行加起来80多行,核心功能代码就是fopen这个资源文件:

if ((fp = fopen(argv[1], "r")) != NULL)

从文件头取到(getc(fp))到EOF,fprintf(stdout,"0x%02x",ch):

for (p = 0; (length < 0 || p < length) && (ch = getc(fp)) != EOF; p++)
{
    char *c = p ? ",\n  " : "  ";        
    fprintf(fpo, "%s0x%02x", (p % COLS) ? ", " : c, ch);
}

Download

已收录至Cocoa-Utilities: https://github.com/Sundae/Cocoa-Utilities



转载于:https://www.cnblogs.com/elfsundae/archive/2011/07/18/2109056.html

Cocoa/iPhone App/静态库 嵌入资源文件 rtb v0.1发布相关推荐

  1. ios开发 c语言打包.a文件,【转】IOS静态库a文件制作流程

    原文网址:http://www.jianshu.com/p/3439598ea61f 1.新建Cocoa Touch Static Library工程 新建工程 2.Xcode的参数设置 " ...

  2. iOS静态库.a文件制作和导入使用

    iOS静态库.a文件制作: 1.新建Cocoa Touch Static Library工程 新建工程 - 选择iOS-FrameWork&Libary,选择 Cocoa Touch Stat ...

  3. iOS架构-分离静态库.a文件并导出.m伪代码文件(11)

    之前合成了静态库.a, 有时候我们会拿到别人提供的静态库,但是编译报错,这时候最先要考虑的一步就是这个静态库是否支持我们编译的架构.怎么查看支持的架构?废话不多说!下面亲自实验一下 第一步: 准备一个 ...

  4. iOS如何查看静态库.a文件支持的cpu类型

    打开终端: 输入 lipo -info 然后将你要查看的静态库.a 文件找到,拖入 -info 后边.假设路径为A,即为 lipo -info A 回车键,然后就会看到静态库是否支持 armv7,ar ...

  5. ar - 创建静态库.a文件

    用途说明 创建静态库.a文件.用C/C++开发程序时经常用到,但我很少单独在命令行中使用ar命令,一般写在makefile中,有时也会在shell脚 本中用到.关于Linux下的库文件.静态库.动态库 ...

  6. iOS如何查看静态库.a文件是否支持i386?

    打开终端: 输入 lipo -info 然后将你要查看的静态库.a 文件找到,拖入 -info 后边.假设路径为A,即为 lipo -info A 回车键,然后就会看到静态库是否支持 armv7,ar ...

  7. xcode 制作静态库.a文件 详解

    http://blog.csdn.net/kepoon/article/details/21516977 最近在做Apple的IOS开发,有开发静态库的需求,本身IOS的开发,只允许静态库或者Fram ...

  8. VS2019创建和使用静态库(.lib文件)

      我把我的静态双向链表和图都制作成了静态库放到了我的Gitee上,如果需要使用调库可以来我的Gitee下载.魔术师的徒弟的的Gitee 一.静态库的创建   首先,创建一个空项目:   把头文件和实 ...

  9. linux静态库添加文件,Linux静态库和动态库的编写和使用

    Linux静态库和动态库的编写和使用 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 1  静态库和动态库的区别 1.1. 静态函数库 (1)静态函数库的名 ...

最新文章

  1. iOS主线程耗时检测方案
  2. 【论文解读】Confluence:物体检测中不依赖IoU的NMS替代算法论文解析
  3. 嵌入式之NB-IoT开发与应用01【移动通信网络发展概述、NB-IoT应用案例、物联网生态系统-解决方案、智慧消防项目需求分析及系统设计】
  4. jmap java opts_jmap --查看JVM内存使用详情
  5. mysql分区功能详细介绍,以及实例
  6. 安卓微软雅黑字体ttf_618巨献丨精致的悦黑5字重小字体
  7. python自动化办公 51cto_聊聊 Python 办公自动化之一 Excel
  8. 关于esp32的省电模式的WiFi连接
  9. 在div 底部显示背景图片
  10. Django之tag标签和filter标签
  11. MVC之在实例中的应用
  12. java file文件删除_Java File.delete 删除文件
  13. linux双系统 引导修复,Linux与windows双系统GRUB引导修复
  14. ENVI裁剪影像重叠区域(非矩形)
  15. Word中公式输入的快捷键
  16. 戒指戴在不同的手指上代表的意思
  17. 内存分配函数总结- 陈敏的博客- CSDN博客
  18. 大学三年来的心路历程分享
  19. java图片上传数量限制_bootstrap fileinput实现限制图片上传数量及如何控制分批多次上传...
  20. 操作系统发展趋势分析,以及对开发者的影响。

热门文章

  1. Python装饰器之property()详解
  2. 【ARM】ARM汇编程序设计(六) stm和ldm
  3. 【Linux系统编程应用】 Linux系统中找不到设备/dev/fb0
  4. python素材库_python的JSON库
  5. mac你没有权限打开应用程序_苹果mac卡顿怎么解决呢?轻松几招让你Mac流畅如新
  6. 分段函数插值法c语言代码实验,实验名称插值法汇总.doc
  7. 学习MFC首先要知道的--程序执行顺序
  8. Emscripten-mac安装与升级
  9. C++创建对象的两种方式
  10. 增长量计算n+1原则_土方量计算方法