作者:link [img594ca61c8d41d.jpg] 概述 为什么要在node.js中调用动态链接库 由于腾讯体系下的许多公共的后台服务(L5, CKV, msgQ等)已经有了非常成熟的C.../C++编写的API,以供应用程序调用,node.js作为在公司内新兴的后台runtime在调用这些公共服务的时候没必要再造一遍轮子,而是可以将这些API编译成.so文件直接使用。...对于一些密集计算型的任务可以由C++编写好模块,生成.so文件后由node.js调用。 ffi简介与安装 我们使用node-ffi来帮助我们调用动态链接库。...并且,如果你使用的node.js版本是4.0+,node-gyp的安装依赖支持C++11语法的gcc,你需要确定当前环境的gcc版本至少高于4.8。...下面是如果利用ffi在nodejs中调用这个接口,该接口的源码已经被封装成libsend_msg.so这个动态链接库了,我们直接调用就好。
概述 为什么要在node.js中调用动态链接库 由于腾讯体系下的许多公共的后台服务(L5, CKV, msgQ等)已经有了非常成熟的C/C++编写的API,以供应用程序调用,node.js作为在公司内新兴的后台...对于一些密集计算型的任务可以由C++编写好模块,生成.so文件后由node.js调用。 ffi简介与安装 我们使用node-ffi来帮助我们调用动态链接库。...并且,如果你使用的node.js版本是4.0+,node-gyp的安装依赖支持C++11语法的gcc,你需要确定当前环境的gcc版本至少高于4.8。...ldconfig命令的主要用途是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib.so),进而创建出动态装入程序...下面是如果利用ffi在nodejs中调用这个接口,该接口的源码已经被封装成libsend_msg.so这个动态链接库了,我们直接调用就好。
本文作者:IMWeb link 原文出处:IMWeb社区 未经同意,禁止转载 概述 为什么要在node.js中调用动态链接库 由于腾讯体系下的许多公共的后台服务(L5, CKV, msgQ等...)已经有了非常成熟的C/C++编写的API,以供应用程序调用,node.js作为在公司内新兴的后台runtime在调用这些公共服务的时候没必要再造一遍轮子,而是可以将这些API编译成.so文件直接使用。...对于一些密集计算型的任务可以由C++编写好模块,生成.so文件后由node.js调用。 ffi简介与安装 我们使用node-ffi来帮助我们调用动态链接库。...并且,如果你使用的node.js版本是4.0+,node-gyp的安装依赖支持C++11语法的gcc,你需要确定当前环境的gcc版本至少高于4.8。...下面是如果利用ffi在nodejs中调用这个接口,该接口的源码已经被封装成libsend_msg.so这个动态链接库了,我们直接调用就好。
FFI 可用于加快程序执行(这在 Python 或 Ruby 这类动态语言中很常见),或者只是因为你想使用一些其他语言编写的库(例如 TensorFlow 的核心库是用 C++ 写的,并暴露了 C API...为 Rust 库编写 FFI 并不难,但是却有一些挑战和可怕的部分,主要是你要使用指针和 unsafe 块1。...在这篇文章中,我将讲述我对 Rust 和 FFI 的经验,基于 battery-ffi ,它将 FFI 暴露给我的另一个 crate — battery。...[dependencies] libc = "*" [lib] crate-type = ["cdylib"] 将 FFI 层与 “主” 库分离出来,并将不安全的代码转移到一个新的 crate,这可能是一个好主意...另外,默认情况下 Rust 库使用 crate-type = ["rlib"],而 FFI 因该是 cdylib。
Rust 语言对 FFI 有比较完善的支持。本节主要讲在基础设施层面,Rust 语言对 FFI 的支持。...标准库 std:os:raw 模块 std:ffi 模块 1....标准库 在实际开发 Rust 语言与其它语言相互调用的程序时,会遇到需要相互传递参数的情况。Rust 标准库std::os::raw 和std::ffi 这两个模块提供了这方面的支持。...2.1 std::os::raw 模块 使用 FFI 进行交互的代码通常会使用到 C 语言提供的基本类型,标准库 std::os::raw 模块[2]提供了一些类型与 C 语言定义的类型相匹配,以便与...2.2 标准库 std::ffi 模块 由于 Rust 语言中字符串与 C 语言字符串的不同之处,标准库 std::ffi 模块[3]提供了一组实用的程序,主要用于外部函数接口 FFI 的绑定,以及用在与其他语言传递类
这节我们主要关注 Rust 导出共享库时的错误处理。...Option 和 Result 的处理 在 FFI 中允许使用任何T: Sized的Option和Option,代替显式地进行无效性(nullity )检查的指针。...在设计 Rust 导出共享库时,我们可以使用返回值的错误处理机制,使 C 调用者可以通过检查返回值来检测何时发生了错误,并获得相关的错误信息。...同时跨越 FFI 边界的panic会导致未定义的行为(Undefined Behavior,UB),我们还需要确保我们的 FFI 绑定是异常安全(Exception Safety)的。...也就是说如果 Rust 导出库的代码可能会出现panic,则需要有个处理机制。在 FFI 绑定时我们可以使用catch_unwind将其包含在 Rust 中,从而不跨越 FFI 边界。
这一篇我们来探讨Rust导出共享库时如何传递字符串,主要涉及字符串作为函数参数和函数返回值的处理细节。...我们首先回顾关于字符串的基础知识,了解其在Rust和C中的区别,然后设计具体的示例进行实践,并整理出传递字符串的FFI编程范式。 基础知识 在 C 语言中,字符串可看作是由字符组成的一维的字节数组。...出于内存安全的考虑,字符串被分为了很多种类型来表示,我们来看一张图。 ? 我们简单介绍以下几个类型,其余类型可以看 Rust 标准库的文档。...str:这是 Rust 语言核心中仅有的一种字符串类型,Rust 标准库中提供了其它的字符串类型。...在 Rust 标准库中提供了对字符串按字符处理(chars())和按字节(bytes())处理的操作支持,其中单个字符是用char类型来表示,而使用u8来表示字节类型。
本章,我们继续来玩耍跨Rust 和 C FFI边界的指针。...设计 本节,我们设计这样一个示例: 示例 1 Rust 导出一个 so 库 main 函数在 C 这边,链接 Rust 的 so 库 C 中分配栈内存,交由 Rust 端填充 Rust 端打印 C 端打印...感觉已经没什么可讲的了。看过本教程之前内容的同学,应该会秒懂。 接着来看示例2的代码。 示例2的代码 示例2的代码,Rust 这边没有变化。...示例2的C语言这边是在堆上 malloc 了一块内存,所以程序结束的时候,要记得 free 掉。 我们从两个示例的对比可以看到,C 这边栈和堆的指针,都可以用相同的 Rust 的代码。...结论 本章通过构造两个示例,演示了 Rust导出共享库 的一个操作场景,例子清晰明了,可细品。
本节主要介绍 Rust 导出共享库时,如何通过指针在 Rust 和 C 之间传递结构体。上一节的示例是结构体的内存在 C 端分配,本节介绍内存在 Rust 这边分配,由 C 填充和使用。...设计 本节的示例: Rust 中导出共享库,包含三个函数: student_new,Rust 端分配内存并用默认值初始化,由 C 端填充和更新; student_alice,Rust 端分配内存并初始化...,由 C 端使用; student_free,供 C 端用来释放结构体的内存 C 中定义main函数,链接 Rust 的共享库,并调用相关函数; 实现 工程的初始化类似之前的导出共享库示例,导出.so的共享库要在...结论 本文通过设计一个示例,演示了 Rust 导出共享库时,提供内存分配和释放的函数,通过指针传递结构体,并在 C 端完美实现使用和更新结构体。...本章示例的所有代码:https://github.com/lesterli/rust-practice/tree/master/ffi/example_03。
const Foo, x: isize, y: isize) -> isize { let foo = &*foo; foo.method3(x, y) } 然后,用这个接口层代码编译出动态链接库,...那么,我们实现 FFI 层的时候,需要这样写: #[no_mangle] extern "C" fn buffer_print_i32(buf: Buffer) { ... } #[no_mangle...size_t len; }; void buffer_print_i32(Buffer_i32 buf); void buffer_print_f32(Buffer_f32 buf); 可见,我们在 FFI...,就是变体中还带数据负载的枚举,类似下面这种: enum Foo { Bar(String), Baz, } 既然此处我们是要研究与C的对应关系,其实真正Rust要导出共享库给C使用的场景...组合指定 #[repr(C, u8)] #[repr(C, u16)] 组合指定只能用在带负载枚举上(但是带负载枚举在实际场合中,跨FFI边界的场景并不多,如果有必要,后面开专题说明)。
有了这种基本思维模型后,我们用 Rust 进行 FFI 编程,就会心中有数,知道什么时候该做什么,不再是一团浆糊了。 从本篇开始,我们进入新的领域:在 C 代码中调用 Rust 的功能。...调用加法函数,并打印 Rust 代码: // 在 Cargo.toml 中,加入如下两行 [lib] crate-type = ["cdylib"] 要让 Rust 导出动态共享库,需要在 Cargo.toml...会在 target/debug/ 下生成 lib{cratename}.so (我们这里为 librustffi3.so)这个动态链接库文件。...C 向 Rust 传入一个数组计算元素的和并返回 前面两个例子是最简单的整型类型的参数传递,能说明 Rust 导出共享库的基本样板操作。但在函数参数这块儿,能说明的问题有限。...总结 本篇,我们研究了 Rust 导出动态链接库给 C 用的基本形式和规范。下一篇,我们会探讨字符串作为函数参数和返回值传递的细节。
,还是太复杂了,最后还是回归到 Rust Nomicon Book 中的 FFI 小节所举的例子:snappy。...但可惜,它更多地是一本内部技术参考,而不是一本给初学者看的教程。在 FFI 这一节,也是讲得过于简略,并不适合作为初学者入门之用。本篇会大量摘取其中的内容。...因为我们现在做的正是对 snappy 库的 Rust 封装。snappy 库是 C 写的,编译后,(一般)形成动态链接库,安装在系统约定路径中。...其在设计之初,就强调了与 C 生态的无缝结合这个目标。同时也让 Rust 具有了对底层系统强大而精确的描述能力。厉害! FFI 好像很简单 不~~ 不是那么简单!...如果 FFI 编程,只有这么简单就好啦。我们在本篇,其实只是选了一个最简单的库。
,初始化,并打印; 在 Rust 中,调用 C 中的 fill_data 填充结构体,并调用 C 中的 print_data 打印; 在 Rust 中,再次打印 C 填充后的结构体数据。...(raw: *mut T) -> Box 所有权分析如下: (1)首先使用Box分配一块堆内存,并使用 Box::into_raw 函数(标准库描述:https://doc.rust-lang.org...(3)最后在 Rust 端再次打印填充后的数据,其中使用了 Box::from_raw 函数(标准库描述:https://doc.rust-lang.org/beta/std/boxed/struct.Box.html...std::rt::lang_start (rt.rs:67) ==13973== by 0x10E289: main (in /data/github/lester/rust-practice/ffi...完整的示例代码:https://github.com/lesterli/rust-practice/tree/master/ffi/example_09
同时我们也知道 Rust 中的所有的闭包都实现了由标准库提供的 trait Fn、FnMut 或 FnOnce 中的一个。...因此,从理论上讲,我们应该能够通过将闭包“拆分”为两部分,匿名类型的实例数据和某种类似call()方法的函数。这样我们可以获取其中函数部分的指针,从而实现将闭包传递给 C 端代码。...和get_callback,代码如下: // ffi/example_10/src/main.rs unsafe extern fn hook(result: c_int, user_data...我们使用闭包的原因是需要事先定义一段代码,并在之后的某个时候才实际调用它。这里我们将期望调用的代码储存在了 closure 中。...本篇的完整代码位于:https://github.com/lesterli/rust-practice/tree/master/ffi/example_10
具体可参见标准库文档 fn,解释得非常详尽。 函数指针的功能就是指向函数代码片断,可以用函数指针来调用函数,效果跟函数名一样,如上面 C 代码中的 cb(result)。...其实我们遇到的问题,在 C 的领域,早就是一种常见的问题(比如一个 GUI 库的回调函数),所以其实也早就有对应的解决方案,比如,使用 C 中的魔幻主义的 void * 携带一个数据块传递。...从标准库页面可以学习到,Rust 中的 *const c_void 等于 C 的 const void*,Rust 中的 *mut c_void 等于 C 的 void*。...达成我们的理想要求。 总结 在本篇,我们研究了 Rust 与 C 如何跨 FFI 边界实现回调函数的调用,以及在回调中更新外部数据。...全篇内容,主要参考: http://adventures.michaelfbryan.com/posts/rust-closures-in-ffi/ 感谢作者的精彩分享 Rust 标准库文档 文章中的代码在
本篇是《手动绑定 C 库入门》的第二篇。了解第一篇后,我们知道在调用 C 库时,需要重新在 Rust 中对该 C 库中的数据类型和函数签名进行封装。...备注:有自动生成绑定的工具,比如,bindgen可以自动生成 C 库和某些C ++库的 Rust FFI 绑定。但这个章节不涉及这些。...// ffi/rust-call-c/src/array.rs use std::os::raw::c_int; // 对 C 库中的 sum 函数进行 Rust 绑定: extern "C" {...#[repr(C)] pub struct OpaqueObject { _private: [u8; 0], } 同样的,对该 C 库中的函数进行 Rust FFI 手动绑定,示例如下: extern...总结 在 Rust 中调用 C 库,进行 Rust FFI 绑定: 传递结构体类型的参数时,可以使用repr属性#[repr(C)]确保有一致的内存布局。
第一个示例: // ffi/rust-call-c/src/c_utils.c int sum(const int* my_array, int length) { int total = 0.../rust-call-c/src/array.rs use std::os::raw::c_int; // 对 C 库中的 sum 函数进行 Rust 绑定: extern "C" { fn...create, print, release C端代码编译成 .so 动态库 这三个函数,导入到Rust中使用 在Rust中,调用C的create函数,创建一个资源,并拿到指针 在Rust中,利用这个指针...实现了我们这个场景下的核心要求,资源在C那边管理,Rust这边只是借用。但是填数据又是在Rust这边。 搜索标准库,我们会发现,Vec也有这两个方法。这其实是对应的。...因为在这种跨FFI边界调用的情况下,内存的分配,完全可能不是同一个分配器做的,混用会出各种 undefined behaviour。所以,这些细节一定要注意。
从 编 译 C 动 态 库 到 php 的 FFI 拓 展 使 用要求版本FFI *没有安装 FFI 拓展,自行安装编写C代码新建 demo.c 文件// 包含c的stdio库(根据实际情况添加文件头)...环境使用gcc编译动态库gcc 参数后面指定你要编译的文件,这里是 demo.c。...根据你的实际情况修改-shared 参数表示生成动态库。-o 参数后面指定输出的动态库文件名,这里是 demo.so。...(根据实际情况修改)-o 参数后面指定输出的动态库文件名,这里是 demo.dll。...安装 FFI 依赖库apt install libffi-dev执行phpize文件phpize配置编译选项。
luajit ffi 小结 ---- Lua 是一种语法简单,上手快的语言,虽然原生库比较少,但是可以方便的和 C 语言互相调用,常被用于脚本嵌入到 C 程序中。...使用 Lua 调用 C 函数的 Lua 库,使用该库,Luaer 不用再去操作复杂的 Lua 栈来粘合两种程序代码,luajit ffi 官方资料。...引入 luajit ffi 库 local ffi = require("ffi") 在 Lua 中调用 C 函数 和 lua 的 C API 一样,Lua 调用 C 函数,需要将 C 函数编译成链接库...ffi.load(name [,global]) 这里第二个参数如果为 true,则该库被引入全局命名空间,这里使用 ffi.load 需要注意两点: 链接库文件必须在 C 的动态链接库查找路径中,否则会报类似错误...C 程序查找动态链接库相同,如上面我生成的动态链接库文件为 libffimyc.so,我在 ffi.load 中的 name 为 ffimyc 调用自己的函数,可以直接使用 ffi.load 返回的变量调用
【运行时】FFI链接C ABI动态链接库(实操分享) 不需要依赖任何第三方crate就可达成·运行时·链接的功能要求。至于使用第三方crate所带来的好处,我将在文章末尾给出解释与列举。...否则,在编译过程中,会出现“找不到链接库”的错误= note: ld.exe: cannot find -l。...支持以Cargo Package根目录为起点的【相对路径】。 native=前缀表示:在该下预存都是C ABI链接库,而不是Rust ABI链接库。...即,使【C ABI动态链接库】对编译输出的.exe文件可见。...),创建一个指向【C ABI动态链接库(文件)】的【符号链接】。
领取专属 10元无门槛券
手把手带您无忧上云