-
Notifications
You must be signed in to change notification settings - Fork 2.2k
C 函数调用
接入扩展 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")
上述第三步,定义 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*
。
注意:
- 所有的指针类型都用
void *
代替。 - 暂不支持 struct 类型和 block 类型。
JPCFunctionBinder 里有一些手动绑定的 C 函数扩展,在 JPCFunction 诞生之前,JSPatch 中 C 函数的调用是通过事先在 OC 层针对每一个要调用的 C 函数进行一层 JS 绑定实现的,之前 JSPatch 项目已经实现过一些 UIKit / CoreGraphics 相关 C 函数的绑定,为了跟 JPCfunction 区分开,目前这样的绑定扩展都放在 JPCFunctionBinder 中。JPCFunctionBinder 与 JPCFunction 没有关系。
虽然对每个 C 函数进行绑定很不灵活,无法让 JSPatch 动态调用所有 C 函数,但 JS 调用手动绑定后的 C 函数性能上会比通过 JPCFunction 动态调用的方式高 5倍 左右,对于性能要求高的情况还是可以选择手动绑定的方式。手动绑定方式详见 创建扩展