如何从其他语言访问Rust

排挤

以前,当代码库为C ++时,我有C ++包装文件,这些文件会链接到代码库,然后运行swig(C ++ 11支持的第3版)以生成目标语言(Python,JavaScript, C#等)。然后,当然将所有这些文件和库编译成一个共享库,并从所需的语言中调用它。现在,代码库已更改为rust。因此,为了使wig工作,我需要以下内容:

  1. 主锈代码文件编译成rlib。
  2. Rust包装器文件,它调用主代码库,但使用no_mangleextern语法FFI并编译成staticlib。
  3. 称为生锈包装纸的AC文件,是生锈包装纸的副本。

现在,我swig在C文件上使用,获取目标语言的接口文件,将所有文件(步骤2和3)和SWIG接口文件组合在一起)成一个共享对象,然后从目标语言进行调用。

所以:

  1. 这个方法好吗?

  2. 我可以使用免费功能。但是我对如何使成员函数(方法)工作感到困惑。在C ++中,成员函数的第一个参数是隐式this指针。因此,我可以void*将类句柄或结构的C接口返回,将其传递给其他想要存储它的人(例如Firefox的jsctypes),然后再次将reinterpret_cast接收为具体/实际类型并调用成员函数在上面。如何使用Rust做到这一点?

例如,对于

pub struct A { id: SomeType, }
impl A {
    pub fn some_funct_0(&mut self) {}
    pub fn some_funct_1(&self) {}
}

impl SomeTrait for A {
    fn some_trait_funct(&mut self) {}
}

那么,如何A从目标语言(Python,C等)(甚至只是C接口)的对象上访问这些成员函数(应该是非托管的,我猜是在堆上?)?

弗拉基米尔·马特维耶夫(Vladimir Matveev)

好的,方法只是常规函数,正如克里斯所说,self参数与Self类型具有隐式联系对于您的示例(稍作修改),使用C代码中的函数应该很简单:

#[repr(C)]
pub struct A { id: u32, }

#[no_mangle]
pub extern fn new_a(id: u32) -> A {
    A { id: id }
}

impl A {
    #[no_mangle]
    pub extern fn some_funct(&self) {
        println!("Called some_funct: {}", self.id);
    }
}

trait SomeTrait {
    extern fn some_trait_funct(&self);
}

impl SomeTrait for A {
    #[no_mangle]
    extern fn some_trait_funct(&self) {
        println!("Called some_trait_funct: {}", self.id);
    }
}

请注意,我添加extern了更改调用约定,并#[no_mangle]避免#[repr(C)]在结构上进行名称修饰的操作。如果您的代码创建Box结构的es并将它们作为原始指针传递给C,则后者是不必要的但是,我不确定#[no_mangle]如果有多个特征实现者,如何影响特征方法-如果两者都具有#[no_mangle],那么必然会发生某种名称冲突。

现在使用这种类型及其在C中的功能很容易:

#include <stdint.h>

struct A {
    uint32_t id;
};

extern struct A new_a(uint32_t id);
extern void some_funct(const struct A *self);
extern void some_trait_funct(const struct A *self);

int main() {
    struct A a = new_a(123);
    some_funct(&a);
    some_trait_funct(&a);
}

该程序可以编译并运行:

% rustc --crate-type=staticlib test.rs
multirust: a new version of 'nightly' is available. run `multirust update nightly` to install it
note: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: System
note: library: pthread
note: library: c
note: library: m
% gcc -o test_use test_use.c libtest.a -lSystem -lpthread -lc -lm
% ./test_use
Called some_funct: 123
Called some_trait_funct: 123

如果接受方法&mut self

#[no_mangle]
extern fn some_funct_mut(&mut self) { ... }

您将需要省略const

extern void some_funct_mut(struct A *self);

如果接受方法self

#[no_mangle]
extern fn some_funct_value(self) { ... }

您将需要按值传递结构:

extern void some_funct_value(struct A self);

尽管如果通过不透明的指针使用该结构,则调用按值将其取值的函数可能很困难,因为C必须知道该结构的确切大小。我相信,不透明指针并不常见。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何向TeX添加其他语言

来自分类Dev

如何更改其他应用的语言环境?

来自分类Dev

Twilio如何听到其他语言的数字?

来自分类Dev

如何用其他语言解析日期?

来自分类Dev

使用其他编程语言访问数据库

来自分类Dev

如何使用默认语言以外的其他语言启动Firefox?

来自分类Dev

如何从其他目标访问数组(KeyboardViewController)

来自分类Dev

如何访问ResourceDictionary中的其他资源

来自分类Dev

如何从其他表格访问列表

来自分类Dev

如何从其他功能访问文件

来自分类Dev

如何从其他方法访问变量

来自分类Dev

如何访问其他类中的对象?

来自分类Dev

如何访问模型孩子的其他父母

来自分类Dev

如何访问其他布局的元素?

来自分类Dev

如何从其他类访问的DefaultTableModel

来自分类Dev

如何从其他ViewModel访问数据?

来自分类Dev

如何从其他ViewModel访问数据?

来自分类Dev

如何访问其他类中的变量

来自分类Dev

如何从其他线程访问QWidget

来自分类Dev

如何访问其他对象的功能

来自分类Dev

如何访问其他布局的元素?

来自分类Dev

Ansible:如何访问其他主机的变量?

来自分类Dev

如何从其他文件访问函数?

来自分类Dev

如何从 React 访问其他 .js 文件

来自分类Dev

如何使C枚举类型可用于其他语言?

来自分类Dev

如何在Kubuntu 16.04 LTS中安装其他语言?

来自分类Dev

Bash,如何使用其他语言环境打印日期

来自分类Dev

如何让Android布局文件知道选择了其他语言

来自分类Dev

如何在Kubuntu 16.04 LTS中安装其他语言?