Quantcast
Channel: Essence Sharing | 干货分享 - iOSRE
Viewing all articles
Browse latest Browse all 301

尝试解决从 class-dump 中导出的头文件不能直接编译的问题

$
0
0

@ChiChou wrote:

在做插件开发的时候,需要声明一些应用中自带的类结构。可以使用 class-dump 直接导出头文件:

class-dump -H executable -o PrivateHeaders

但我在直接拿到 Xcode 中编译的时候会遇到不少错误,总结了几个常见的:

缺少 NSObject.h

生成的许多头文件会包含 #import "NSObject.h" 一行,但生成的目录中没有这个文件。实测可以使用 Foundation/NSObject.h,可以批量替换头文件里的关键字,也可以直接在目录中创建一个 NSObject.h 引入之。

生成的文件名带有 -Protocol 后缀导致不匹配

编译的时候还会遇到大量的头文件找不到的问题,发现 class-dump 给一部分头文件加上了 -Protocol.h 后缀,写一个循环重命名,搞定

selector 中包含 .cxx_destruct

部分 class 的 selector 包含 - (void).cxx_destruct;,删除即可

block 参数

部分头文件方法中会遇到 CDUnknownBlockType 类型,如这个帖子(http://bbs.iosre.com/t/hook-block/3184)。改成 id 可以编译。

如果有其他的问题,等我遇到了再继续补充……

由于 Mac 自带的 sed 功能残缺,需要 brew install gnu-sed

#!/bin/bash
#
# NOTE: You need to `brew install gnu-sed` on Mac
# 
# by @codecolorist
# http://github.com/chichou
# 
# fix some compilation error of headers generated by class-dump
#
# usage: fixheader.sh DIRECTORY


usage() {
  echo "Fix compilation error of headers generated by class-dump"
  echo
  echo "Usage: $0 {PATH}"
}

if [ ! -d "$1" ]; then
  echo "Invalid path $1"
  usage
  exit 1
fi

for filename in $1/*.h; do
  if [ 'Darwin' == $(uname) ]; then
    sed="gsed"
  else
    sed="sed"
  fi

  # remove "- (void).cxx_destruct;"
  # replace "CDUnknownBlockType" with "id"
  # fix missing NSObject.h

  $sed -i -e '/- (void).cxx_destruct;/d' -e "s/\bCDUnknownBlockType\b/id/g" \
    -e "s/#import \"NSObject.h\"/#import <Foundation\/NSObject.h>/" $flag $filename

  # remove -Protocol suffix
  if [[ $filename == *"-Protocol.h" ]]; then
    echo "rename $filename"
    mv "$filename" "${filename%-Protocol.h}.h";
  fi

done;

Posts: 7

Participants: 3

Read full topic


Viewing all articles
Browse latest Browse all 301

Trending Articles