“FFI” 的全名是 Foreign Function Interface,通常指的是允许以一种语言编写的代码调用另一种语言的代码。而 “Libffi” 库只提供了最底层的、与架构相关的、完整的”FFI”,因此在它之上必须有一层来负责管理两种语言之间参数的格式转换。

高级语言编译器产生代码时都会依据一系列的规则,这些规则十分必要,特别是对独立编译来说。其中之一是“调用约定” (Calling Convention),它包含了编译器关于函数入口处的函数参数、函数返回值的一系列假设。它有时也被称作“ABI”(Application Binary Interface)。调用约定(Calling Conventions)定义了程序中调用函数的方式,它决定了在函数调用的时候数据(比如说参数)在堆栈中的组织方式。

通常来说函数调用要用到的两条基本的指令:”CALL”指令和”RET”指令。”CALL”指令将当前的指令指针(这个指针指向紧接在CALL指令后面的那条指令)压入堆栈,然后执行一条无条件转移指令转移到新的代码地址。”RET”是与”CALL”指令配合使用的指令,在绝大多数函数中它是最后一条指令。”RET”指令弹出返回地址(就是早些时候”CALL”指令压入堆栈的地址)并将其加载到”EIP”寄存器中,然后从这个地址开始继续执行。

图1-1 说明调用约定”stdcall”的调用过程,调用时,最末一个参数最先压入堆栈,而由被调用函数使用RET指令清栈。RET指令带有一个操作数,该操作数指明在EIP跳回主要函数之前需要释放的堆栈空间的字节数。这就是说,stdcall调用约定中RET指令带的操作数往往就意味着函数一共传入几个参数。

图1-1 stdcall调用

独立编译时,调用一个函数除了要知道函数的签名外,还要知道其调用约定。比如 Delphi 中调用”Stdcall”的”VC++”的函数,需对调用约定加以声明。

Procedure ShowMess (h :HWND; mess :PChar ); Stdcall; external LibName;

“LibFFI”针对这些不同的调用约定,提供一个高层次的可移植的API,只需调用这些API就可以在运行时进行动态的函数调用。(这种方式和函数指针不同,函数指针比如在编译时就决定了函数的类型,而”libffi”可以在运行时是才决定被调用函数的类型)。有了 libffi ,我们就有可能写出一个通用而且简洁的调用 C 函数的方法。

目前有许多项目都使用了 libff ,包括 ruby,cpython, openjdk,dalvik vm 等等。例如在 Ruby 中,利用 rubyffi (包装了 libffi )可以如此动态地调用一个 dll

介绍内容来自:http://blogs.ejb.cc/archives/1502/libffi-example-of-the-use

http://www.sourceware.org/libffi/
https://github.com/atgreen/libffi
http://www.oschina.net/p/libffi
-----------------------------------------

外部函数接口 LibFFI的更多相关文章

  1. JNI的又一替代者—使用JNR访问Java外部函数接口(jnr-ffi)

    1. JNR简单介绍 继上文“JNI的替代者—使用JNA访问Java外部函数接口”,我们知道JNI越来越不受欢迎,JNI是编写Java本地方法以及将Java虚拟机嵌入本地应用程序的标准编程接口.它管理 ...

  2. 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测

    概述 单测是提升软件质量的有力手段.然而,由于编程语言上的支持不力,以及一些不好的编程习惯,导致编写单测很困难. 最容易理解最容易编写的单测,莫过于独立函数的单测.所谓独立函数,就是只依赖于传入的参数 ...

  3. Jmeter外部函数引用

    Jmeter外部函数引用 1.Beanshell引用Jmeter变量 添加用户自定义变量,输入变量名称和变量值,添加Debug sampler,用于输出初始变量值.

  4. IO端口和IO内存的区别及分别使用的函数接口

    每个外设都是通过读写其寄存器来控制的.外设寄存器也称为I/O端口,通常包括:控制寄存器.状态寄存器和数据寄存器三大类.根据访问外设寄存器的不同方式,可以把CPU分成两大类.一类CPU(如M68K,Po ...

  5. JNI的替代者—使用JNA访问Java外部功能接口

    摘自:http://www.cnblogs.com/lanxuezaipiao/p/3635556.html JNI的替代者-使用JNA访问Java外部功能接口 1. JNA简单介绍 先说JNI(Ja ...

  6. [一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念

      本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程?   java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的 ...

  7. Java 8 函数接口详细教程

    ay = new byte[array.length]; for (int i = 0; i < array.length; i++) { transformedArray[i] = funct ...

  8. 还看不懂同事的代码?Lambda 表达式、函数接口了解一下

    当前时间:2019年 11月 11日,距离 JDK 14 发布时间(2020年3月17日)还有多少天? // 距离JDK 14 发布还有多少天? LocalDate jdk14 = LocalDate ...

  9. 【C/C++开发】【Java开发】JNI的替代者—使用JNA访问Java外部功能接口

    JNI的替代者-使用JNA访问Java外部功能接口 1. JNA简单介绍 先说JNI(Java Native Interface)吧,有过不同语言间通信经历的一般都知道,它允许Java代码和其他语言( ...

随机推荐

  1. iOS 定位服务、通讯录、日历、提醒事项、照片、蓝牙共享、麦克风、相机等授权检测

    金田 iOS系统版本的不断升级的前提,伴随着用户使用设备的安全性提升,iOS系统对于App需要使用的硬件限制也越来越严格,App处理稍有不妥,轻则造成功能不可用用户还不知道,重则会造成App Cras ...

  2. Delphi Dcp 和BPL的解释

    dcp = delphi compiled package,是 package 编译时跟 bpl 一起产生出来的,记录着 package 中公开的 class.procedure.function.v ...

  3. Spring容器的工具类

    代码实现: package com.ht.util; import java.util.Map; import org.springframework.beans.BeansException; im ...

  4. 关于java中private构造函数的问题

    首先推荐以下下面的一篇博客: http://blog.csdn.net/my_dream_fly/article/details/3857887 本来也比较好奇,自己写构造函数总是定义public形式 ...

  5. i&1、负数二进制

    if(i&1==1) 表示 如果是 奇数 则...i&1 -- 按位与运算,取 2进制整数 i 的最低位,如果最低位是1 则得1,如果最低位是0 则得0. 奇数 i 的最低位 是1,偶 ...

  6. [Qt] QString 和 char* 转换

    (1) QString 转 char* char acResult[10240]; //QByteArray baResult = strResult.toLatin1(); QByteArray b ...

  7. 对C++默认构造函数的理解

    在文章开始之前,首先指出对于c++新手的两个常见的误解: 一.任何class如果没有定义default constructor,就会被合成出一个来. 二.编译器合成出来的default constru ...

  8. swift 创建tableView 并实现协议

    import UIKit class ViewController2: UIViewController,UITableViewDelegate,UITableViewDataSource{      ...

  9. Nuget找不到服务器

    Nuget的新地址 http://nuget-prod-v2gallery.trafficmanager.net/api/v2/

  10. 借助共享缓存redis实现分布式锁

    新开发的系统须要控制每一个时刻回收缓存的GC线程有且仅仅有一个在执行,假设有多个线程同一时候执行,会造成系统崩溃.假设仅仅有一个JVM进程那么非常好办.简单的借助synchronizedkeyword ...