Skip to content
bang edited this page Jun 1, 2016 · 11 revisions

接入扩展 Extensions/JPCFunction 后,可以调用项目中任意非内联C函数。

使用方法

1.把 Extensions/JPCFunction 加入项目。

JPCFunction 里包含了 libffi.a 静态库,若出现 ld: library not found for -lffi 错误,请在 XCode Build Settings -> Library Search Paths 里加入 libffi.a 所在目录。

2.在 JS 脚本加载这个扩展。

require('JPEngine').addExtensions(['JPCFunction'])

3.对于要调用的 C 函数,先定义它的参数类型。

defineCFunction("malloc", "void *, size_t")
defineCFunction("NSClassFromString", "Class, NSString *")

4.然后就可以调用这些 C 函数了。

malloc(10)
NSClassFromString("UIView")

defineCFunction 接口

上述第三步,定义 C 函数使用的是 defineCFunction 接口,API如下:

defineCFunction({functionName}, {returnType & paramsType})

第一个参数是函数名,第二个参数是返回值类型和参数类型,用字符串表示,第一个类型为返回值,后续为参数类型。例如这样一个C函数:

int funcA(void *ptr, NSObject *obj, float num) {}

需要这样定义:

defineCFunction("funcA", "void *, NSObject *, float")

目前支持的参数类型有:id, BOOL, int, void, char, short, unsigned short, unsigned int, long, unsigned long, long long, unsigned long long, float, double, bool, size_t, CGFloat, CGSize, CGRect, CGPoint, CGVector, NSRange, NSInteger, Class, SEL, void*

注意

  1. 所有的指针类型都用 void * 代替。
  2. 暂不支持 struct 类型和 block 类型。

与 JPCFunctionBinder 的区别

JPCFunctionBinder 里有一些手动绑定的 C 函数扩展,在 JPCFunction 诞生之前,JSPatch 中 C 函数的调用是通过事先在 OC 层针对每一个要调用的 C 函数进行一层 JS 绑定实现的,之前 JSPatch 项目已经实现过一些 UIKit / CoreGraphics 相关 C 函数的绑定,为了跟 JPCfunction 区分开,目前这样的绑定扩展都放在 JPCFunctionBinder 中。JPCFunctionBinder 与 JPCFunction 没有关系。

虽然对每个 C 函数进行绑定很不灵活,无法让 JSPatch 动态调用所有 C 函数,但 JS 调用手动绑定后的 C 函数性能上会比通过 JPCFunction 动态调用的方式高 5倍 左右,对于性能要求高的情况还是可以选择手动绑定的方式。手动绑定方式详见 创建扩展

Clone this wiki locally