日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/4/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Cocoa/iPhone App/静态库 嵌入资源文件 rtb v0.1发布 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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 // or
13 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发布的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。