你好,我是戴铭。
在 iOS 开发中,我们可以使用 Runtime 接口动态地调用 Objective-C 方法,但是却无法动态调用 C 的函数。那么,我们怎么才能动态地调用 C 语言函数呢?
C 语言编译后,在可执行文件里会有原函数名信息,我们可以通过函数名字符串来找到函数的地址。现在,我们只要能够通过函数名找到函数地址,就能够实现动态地去调用 C 语言函数。
而在动态链接器中,有一个接口 dlsym() 可以通过函数名字符串拿到函数地址,如果所有 C 函数的参数类型和数量都一样,而且返回类型也一样,那么我们使用 dlsym() 就能实现动态地调用 C 函数。
但是,在实际项目中,函数的参数定义不可能都一样,返回类型也不会都是 void 或者 int 类型。所以, dlsym() 这条路走不通。那么,还有什么办法可以实现动态地调用 C 函数呢?
如何动态地调用 C 函数?
要想动态地调用 C 函数,你需要先了解函数底层是怎么调用的。
高级编程语言的函数在调用时,需要约定好参数的传递顺序、传递方式,栈维护的方式,名字修饰。这种函数调用者和被调用者对函数如何调用的约定,就叫作调用惯例(Calling Convention)。高级语言编译时,会生成遵循调用惯例的代码。
不同 CPU 架构的调用惯例不一样,比如 64 位机器的寄存器多些、传递参数快些,所以参数传递会优先采用寄存器传递,当参数数量超出寄存器数量后才会使用栈传递。